aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c')
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c68
1 files changed, 44 insertions, 24 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..e44e18a0112a 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -246,6 +246,7 @@ struct dw_mipi_dsi {
struct clk *pclk;
+ bool device_found;
unsigned int lane_mbps; /* per lane */
u32 channel;
u32 lanes;
@@ -309,13 +310,37 @@ static inline u32 dsi_read(struct dw_mipi_dsi *dsi, u32 reg)
return readl(dsi->base + reg);
}
+static int dw_mipi_dsi_panel_or_bridge(struct dw_mipi_dsi *dsi,
+ struct device_node *node)
+{
+ struct drm_bridge *bridge;
+ struct drm_panel *panel;
+ int ret;
+
+ ret = drm_of_find_panel_or_bridge(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;
+
+ if (!dsi->panel_bridge)
+ return -EPROBE_DEFER;
+
+ return 0;
+}
+
static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,
struct mipi_dsi_device *device)
{
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 +354,14 @@ 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 (!dsi->device_found) {
+ ret = dw_mipi_dsi_panel_or_bridge(dsi, host->dev->of_node);
+ 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->device_found = true;
}
- 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)
@@ -999,6 +1016,16 @@ static int dw_mipi_dsi_bridge_attach(struct drm_bridge *bridge,
/* Set the encoder type as caller does not know it */
bridge->encoder->encoder_type = DRM_MODE_ENCODER_DSI;
+ if (!dsi->device_found) {
+ int ret;
+
+ ret = dw_mipi_dsi_panel_or_bridge(dsi, dsi->dev->of_node);
+ if (ret)
+ return ret;
+
+ dsi->device_found = true;
+ }
+
/* Attach the panel-bridge to the dsi bridge */
return drm_bridge_attach(bridge->encoder, dsi->panel_bridge, bridge,
flags);
@@ -1181,6 +1208,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;
}
@@ -1229,15 +1257,7 @@ EXPORT_SYMBOL_GPL(dw_mipi_dsi_remove);
*/
int dw_mipi_dsi_bind(struct dw_mipi_dsi *dsi, struct drm_encoder *encoder)
{
- int ret;
-
- ret = drm_bridge_attach(encoder, &dsi->bridge, NULL, 0);
- if (ret) {
- DRM_ERROR("Failed to initialize bridge with drm\n");
- return ret;
- }
-
- return ret;
+ return drm_bridge_attach(encoder, &dsi->bridge, NULL, 0);
}
EXPORT_SYMBOL_GPL(dw_mipi_dsi_bind);