Commit c206c7fa authored by Jagan Teki's avatar Jagan Teki Committed by Robert Foss

drm/bridge: dw-mipi-dsi: Find the possible DSI devices

Finding panel_or_bridge might vary based on associated
DSI devices like DSI panel, bridge, and I2C based DSI
bridge.

1. DSI panels and bridges will invoke the host attach
   from probe in order to find the panel_or_bridge.

   chipone_probe()
       dw_mipi_dsi_host_attach().start
	   dw_mipi_dsi_panel_or_bridge()
		...found the panel_or_bridge...

   ltdc_encoder_init().start
       dw_mipi_dsi_bridge_attach().start
		   dw_mipi_dsi_host_attach().start
		       chipone_attach(). start

	               chipone_attach(). done
		   dw_mipi_dsi_host_attach().done
       dw_mipi_dsi_bridge_attach(). done
   ltdc_encoder_init().done

2. I2C based DSI bridge will invoke the drm_bridge_attach
   from bridge attach in order to find the panel_or_bridge.

   ltdc_encoder_init().start
       dw_mipi_dsi_bridge_attach().start
	   dw_mipi_dsi_panel_or_bridge()
		...found the panel_or_bridge...
		   dw_mipi_dsi_host_attach().start
		       sn65dsi83_attach(). start

	               sn65dsi83_attach(). done
		   dw_mipi_dsi_host_attach().done
       dw_mipi_dsi_bridge_attach(). done
   ltdc_encoder_init().done

So, invoke the panel_or_bridge from host attach and
bridge attach in order to find all possible DSI devices.
Signed-off-by: default avatarJagan Teki <jagan@amarulasolutions.com>
Tested-by: default avatarYannick Fertre <yannick.fertre@foss.st.com>
Reviewed-by: default avatarRobert Foss <robert.foss@linaro.org>
Tested-by: default avatarHeiko Stuebner <heiko@sntech.de>
Signed-off-by: default avatarRobert Foss <robert.foss@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20210704140309.268469-1-jagan@amarulasolutions.com
parent 0f3b68b6
...@@ -246,6 +246,7 @@ struct dw_mipi_dsi { ...@@ -246,6 +246,7 @@ struct dw_mipi_dsi {
struct clk *pclk; struct clk *pclk;
bool device_found;
unsigned int lane_mbps; /* per lane */ unsigned int lane_mbps; /* per lane */
u32 channel; u32 channel;
u32 lanes; u32 lanes;
...@@ -309,13 +310,37 @@ static inline u32 dsi_read(struct dw_mipi_dsi *dsi, u32 reg) ...@@ -309,13 +310,37 @@ static inline u32 dsi_read(struct dw_mipi_dsi *dsi, u32 reg)
return readl(dsi->base + 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, static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,
struct mipi_dsi_device *device) struct mipi_dsi_device *device)
{ {
struct dw_mipi_dsi *dsi = host_to_dsi(host); struct dw_mipi_dsi *dsi = host_to_dsi(host);
const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data; const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data;
struct drm_bridge *bridge;
struct drm_panel *panel;
int ret; int ret;
if (device->lanes > dsi->plat_data->max_data_lanes) { 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, ...@@ -329,22 +354,14 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,
dsi->format = device->format; dsi->format = device->format;
dsi->mode_flags = device->mode_flags; dsi->mode_flags = device->mode_flags;
ret = drm_of_find_panel_or_bridge(host->dev->of_node, 1, 0, if (!dsi->device_found) {
&panel, &bridge); ret = dw_mipi_dsi_panel_or_bridge(dsi, host->dev->of_node);
if (ret) if (ret)
return ret; return ret;
if (panel) { dsi->device_found = true;
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) { if (pdata->host_ops && pdata->host_ops->attach) {
ret = pdata->host_ops->attach(pdata->priv_data, device); ret = pdata->host_ops->attach(pdata->priv_data, device);
if (ret < 0) if (ret < 0)
...@@ -999,6 +1016,16 @@ static int dw_mipi_dsi_bridge_attach(struct drm_bridge *bridge, ...@@ -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 */ /* Set the encoder type as caller does not know it */
bridge->encoder->encoder_type = DRM_MODE_ENCODER_DSI; 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 */ /* Attach the panel-bridge to the dsi bridge */
return drm_bridge_attach(bridge->encoder, dsi->panel_bridge, bridge, return drm_bridge_attach(bridge->encoder, dsi->panel_bridge, bridge,
flags); flags);
...@@ -1181,6 +1208,7 @@ __dw_mipi_dsi_probe(struct platform_device *pdev, ...@@ -1181,6 +1208,7 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
#ifdef CONFIG_OF #ifdef CONFIG_OF
dsi->bridge.of_node = pdev->dev.of_node; dsi->bridge.of_node = pdev->dev.of_node;
#endif #endif
drm_bridge_add(&dsi->bridge);
return dsi; return dsi;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment