2018년 07월 26일 00:46에 Andrzej Hajda 이(가) 쓴 글:
> From: Maciej Purski <m.pur...@samsung.com>
> 
> The current implementation assumes that the only possible peripheral
> device for DSIM is a panel. Using an output bridge child device
> should also be possible.
> 
> If an output bridge is available, don't create a new connector.
> Instead, call drm_bridge_attach() and set encoder's bridge to NULL
> in order to avoid an out bridge from being visible by the framework, as
> the DSI bus needs control on enabling its child output bridge.
> 
> Such sequence is required by Toshiba TC358764 bridge, which is a DSI
> peripheral bridge device.
> 
> changed in v5:
> - detach bridge in mipi_dsi detach callback
> 
> Signed-off-by: Maciej Purski <m.pur...@samsung.com>
> [ a.ha...@samsung.com: v5 ]
> Signed-off-by: Andrzej Hajda <a.ha...@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos_drm_dsi.c | 50 ++++++++++++++++---------
>  1 file changed, 32 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
> b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> index 351403f9d245..f5f51f584fa0 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> @@ -255,6 +255,7 @@ struct exynos_dsi {
>       struct mipi_dsi_host dsi_host;
>       struct drm_connector connector;
>       struct drm_panel *panel;
> +     struct drm_bridge *out_bridge;
>       struct device *dev;
>  
>       void __iomem *reg_base;
> @@ -1499,7 +1500,30 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host 
> *host,
>                                 struct mipi_dsi_device *device)
>  {
>       struct exynos_dsi *dsi = host_to_dsi(host);
> -     struct drm_device *drm = dsi->connector.dev;
> +     struct drm_encoder *encoder = &dsi->encoder;
> +     struct drm_device *drm = encoder->dev;
> +     struct drm_bridge *out_bridge;
> +
> +     out_bridge  = of_drm_find_bridge(device->dev.of_node);

Is there any reason to find out_bridge without considering device tree graph 
binding?

Then, you embedded bridge device node in dsi device node[1] but the binding 
document below doesn't mention about this,
Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt

[1] https://lkml.org/lkml/2018/6/19/237

Thanks,
Inki Dae

> +     if (out_bridge) {
> +             drm_bridge_attach(encoder, out_bridge, NULL);
> +             dsi->out_bridge = out_bridge;
> +             encoder->bridge = NULL;
> +     } else {
> +             int ret = exynos_dsi_create_connector(encoder);
> +
> +             if (ret) {
> +                     DRM_ERROR("failed to create connector ret = %d\n", ret);
> +                     drm_encoder_cleanup(encoder);
> +                     return ret;
> +             }
> +
> +             dsi->panel = of_drm_find_panel(device->dev.of_node);
> +             if (dsi->panel) {
> +                     drm_panel_attach(dsi->panel, &dsi->connector);
> +                     dsi->connector.status = connector_status_connected;
> +             }
> +     }
>  
>       /*
>        * This is a temporary solution and should be made by more generic way.
> @@ -1518,11 +1542,6 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host 
> *host,
>       dsi->lanes = device->lanes;
>       dsi->format = device->format;
>       dsi->mode_flags = device->mode_flags;
> -     dsi->panel = of_drm_find_panel(device->dev.of_node);
> -     if (dsi->panel) {
> -             drm_panel_attach(dsi->panel, &dsi->connector);
> -             dsi->connector.status = connector_status_connected;
> -     }
>       exynos_drm_crtc_get_by_type(drm, EXYNOS_DISPLAY_TYPE_LCD)->i80_mode =
>                       !(dsi->mode_flags & MIPI_DSI_MODE_VIDEO);
>  
> @@ -1538,19 +1557,21 @@ static int exynos_dsi_host_detach(struct 
> mipi_dsi_host *host,
>                                 struct mipi_dsi_device *device)
>  {
>       struct exynos_dsi *dsi = host_to_dsi(host);
> -     struct drm_device *drm = dsi->connector.dev;
> -
> -     mutex_lock(&drm->mode_config.mutex);
> +     struct drm_device *drm = dsi->encoder.dev;
>  
>       if (dsi->panel) {
> +             mutex_lock(&drm->mode_config.mutex);
>               exynos_dsi_disable(&dsi->encoder);
>               drm_panel_detach(dsi->panel);
>               dsi->panel = NULL;
>               dsi->connector.status = connector_status_disconnected;
> +             mutex_unlock(&drm->mode_config.mutex);
> +     } else {
> +             if (dsi->out_bridge->funcs->detach)
> +                     dsi->out_bridge->funcs->detach(dsi->out_bridge);
> +             dsi->out_bridge = NULL;
>       }
>  
> -     mutex_unlock(&drm->mode_config.mutex);
> -
>       if (drm->mode_config.poll_enabled)
>               drm_kms_helper_hotplug_event(drm);
>  
> @@ -1654,13 +1675,6 @@ static int exynos_dsi_bind(struct device *dev, struct 
> device *master,
>       if (ret < 0)
>               return ret;
>  
> -     ret = exynos_dsi_create_connector(encoder);
> -     if (ret) {
> -             DRM_ERROR("failed to create connector ret = %d\n", ret);
> -             drm_encoder_cleanup(encoder);
> -             return ret;
> -     }
> -
>       if (dsi->in_bridge_node) {
>               in_bridge = of_drm_find_bridge(dsi->in_bridge_node);
>               if (in_bridge)
> 
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to