Usual I2C configured DSI bridge drivers have drm_bridge_add
in probe and mipi_dsi_attach in bridge attach functions.
With, this approach the drm pipeline is unable to find the
dsi bridge in stm drm drivers since the dw-mipi-dsi bridge is
adding drm bridge during bridge attach operations instead of
the probe.
This specific issue may not encounter for rockchip drm dsi
drivers, since rockchip drm uses component binding operations,
unlike stm drm drivers.
So, possible solutions are
1. Move drm_bridge_add into the dw-mipi-dsi probe.
2. Add mipi_dsi_attach in the bridge drivers probe.
3. Add component binding operations for stm drm drivers.
Option 1 is a relatively possible solution as most of the
mainline drm dsi with bridge drivers have a similar approach
to their dsi host vs bridge registration.
Signed-off-by: Jagan Teki <jagan@xxxxxxxxxxxxxxxxxxxx>
---
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 35 +++++++++----------
1 file changed, 17 insertions(+), 18 deletions(-)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index 6b268f9445b3..8a535041f071 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -314,8 +314,6 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,
{
struct dw_mipi_dsi *dsi = host_to_dsi(host);
const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data;
- struct drm_bridge *bridge;
- struct drm_panel *panel;
int ret;
if (device->lanes > dsi->plat_data->max_data_lanes) {
@@ -329,22 +327,6 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,
dsi->format = device->format;
dsi->mode_flags = device->mode_flags;
- ret = drm_of_find_panel_or_bridge(host->dev->of_node, 1, 0,
- &panel, &bridge);
- if (ret)
- return ret;
-
- if (panel) {
- bridge = drm_panel_bridge_add_typed(panel,
- DRM_MODE_CONNECTOR_DSI);
- if (IS_ERR(bridge))
- return PTR_ERR(bridge);
- }
-
- dsi->panel_bridge = bridge;
-
- drm_bridge_add(&dsi->bridge);
-
if (pdata->host_ops && pdata->host_ops->attach) {
ret = pdata->host_ops->attach(pdata->priv_data, device);
if (ret < 0)
@@ -1105,6 +1087,8 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
struct device *dev = &pdev->dev;
struct reset_control *apb_rst;
struct dw_mipi_dsi *dsi;
+ struct drm_bridge *bridge;
+ struct drm_panel *panel;
int ret;
dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
@@ -1167,6 +1151,20 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
dw_mipi_dsi_debugfs_init(dsi);
pm_runtime_enable(dev);
+ ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0,
+ &panel, &bridge);
+ if (ret)
+ return ERR_PTR(ret);
+
+ if (panel) {
+ bridge = drm_panel_bridge_add_typed(panel,
+ DRM_MODE_CONNECTOR_DSI);
+ if (IS_ERR(bridge))
+ return ERR_PTR(-ENODEV);
+ }
+
+ dsi->panel_bridge = bridge;
+
dsi->dsi_host.ops = &dw_mipi_dsi_host_ops;
dsi->dsi_host.dev = dev;
ret = mipi_dsi_host_register(&dsi->dsi_host);
@@ -1181,6 +1179,7 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
#ifdef CONFIG_OF
dsi->bridge.of_node = pdev->dev.of_node;
#endif
+ drm_bridge_add(&dsi->bridge);
return dsi;
}