Add support for bridge chips connected externally to the i.MX DISP0/DISP1 DPI interfaces. Signed-off-by: Philipp Zabel <p.zabel@xxxxxxxxxxxxxx> --- drivers/gpu/drm/imx/parallel-display.c | 71 ++++++++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c index 2d1fd02..830e56b 100644 --- a/drivers/gpu/drm/imx/parallel-display.c +++ b/drivers/gpu/drm/imx/parallel-display.c @@ -37,6 +37,7 @@ struct imx_parallel_display { u32 bus_format; struct drm_display_mode mode; struct drm_panel *panel; + struct drm_bridge *bridge; }; static enum drm_connector_status imx_pd_connector_detect( @@ -103,8 +104,23 @@ static void imx_pd_encoder_dpms(struct drm_encoder *encoder, int mode) static void imx_pd_encoder_prepare(struct drm_encoder *encoder) { struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); - imx_drm_set_bus_config(encoder, imxpd->bus_format, 2, 3, - imxpd->connector.display_info.bus_flags); + struct drm_connector *connector; + u32 bus_format = imxpd->bus_format; + u32 bus_flags; + + drm_for_each_connector(connector, encoder->dev) { + struct drm_display_info *di = &connector->display_info; + + if (connector->encoder != encoder) + continue; + + bus_flags = di->bus_flags; + if (!bus_format && di->num_bus_formats) + bus_format = di->bus_formats[0]; + break; + } + + imx_drm_set_bus_config(encoder, bus_format, 2, 3, bus_flags); } static void imx_pd_encoder_commit(struct drm_encoder *encoder) @@ -174,15 +190,29 @@ static int imx_pd_register(struct drm_device *drm, drm_encoder_init(drm, &imxpd->encoder, &imx_pd_encoder_funcs, DRM_MODE_ENCODER_NONE, NULL); - drm_connector_helper_add(&imxpd->connector, - &imx_pd_connector_helper_funcs); - drm_connector_init(drm, &imxpd->connector, &imx_pd_connector_funcs, - DRM_MODE_CONNECTOR_VGA); + if (!imxpd->bridge) { + drm_connector_helper_add(&imxpd->connector, + &imx_pd_connector_helper_funcs); + drm_connector_init(drm, &imxpd->connector, + &imx_pd_connector_funcs, + DRM_MODE_CONNECTOR_VGA); + } if (imxpd->panel) drm_panel_attach(imxpd->panel, &imxpd->connector); - - drm_mode_connector_attach_encoder(&imxpd->connector, &imxpd->encoder); + if (imxpd->bridge) { + imxpd->bridge->encoder = &imxpd->encoder; + imxpd->encoder.bridge = imxpd->bridge; + ret = drm_bridge_attach(drm, imxpd->bridge); + if (ret < 0) { + dev_err(imxpd->dev, "failed to attach bridge: %d\n", + ret); + return ret; + } + } else { + drm_mode_connector_attach_encoder(&imxpd->connector, + &imxpd->encoder); + } return 0; } @@ -223,13 +253,30 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data) struct device_node *remote; remote = of_graph_get_remote_port_parent(ep); + if (!remote) { + dev_warn(dev, "endpoint %s not connected\n", + ep->full_name); + of_node_put(ep); + return -ENODEV; + } of_node_put(ep); - if (remote) { - imxpd->panel = of_drm_find_panel(remote); - of_node_put(remote); + + imxpd->panel = of_drm_find_panel(remote); + if (imxpd->panel) { + dev_dbg(dev, "found panel %s\n", remote->full_name); + } else { + imxpd->bridge = of_drm_find_bridge(remote); + if (imxpd->bridge) + dev_dbg(dev, "found bridge %s\n", + remote->full_name); } - if (!imxpd->panel) + if (!imxpd->panel && !imxpd->bridge) { + dev_dbg(dev, "waiting for panel or bridge %s\n", + remote->full_name); + of_node_put(remote); return -EPROBE_DEFER; + } + of_node_put(remote); } imxpd->dev = dev; -- 2.8.1 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel