[PATCH v2 1/5] drm/stm: ltdc: Add bridge support
Andrzej Hajda
a.hajda at samsung.com
Mon May 22 19:11:34 PDT 2017
Hi Philippe,
W dniu 2017-05-20 o 00:20, Philippe CORNU pisze:
> Add the bridge support, used by DSI host and HDMI/LVDS bridges.
>
> Signed-off-by: Philippe CORNU <philippe.cornu at st.com>
> ---
> drivers/gpu/drm/stm/ltdc.c | 74 ++++++++++++++++++++++++++++++++++------------
> drivers/gpu/drm/stm/ltdc.h | 1 +
> 2 files changed, 56 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
> index 7b2d63b..809e420 100644
> --- a/drivers/gpu/drm/stm/ltdc.c
> +++ b/drivers/gpu/drm/stm/ltdc.c
> @@ -858,6 +858,43 @@ static struct drm_encoder *ltdc_rgb_encoder_create(struct drm_device *ddev)
> return encoder;
> }
>
> +static const struct drm_encoder_funcs bridge_encoder_funcs = {
> + .destroy = drm_encoder_cleanup,
> +};
> +
> +struct drm_encoder *bridge_encoder_create(struct drm_device *ddev,
> + struct drm_bridge *bridge)
> +{
> + struct drm_encoder *encoder;
> + int ret;
> +
> + encoder = devm_kzalloc(ddev->dev, sizeof(*encoder), GFP_KERNEL);
> + if (!encoder)
> + return NULL;
> +
> + encoder->possible_crtcs = CRTC_MASK;
> + encoder->possible_clones = 0; /* No cloning support */
> +
> + drm_encoder_init(ddev, encoder, &bridge_encoder_funcs,
> + DRM_MODE_ENCODER_TMDS, NULL);
> +
> + drm_encoder_helper_add(encoder, NULL);
> +
> + /* Link drm_bridge to encoder */
> + bridge->encoder = encoder;
> + encoder->bridge = bridge;
I think the above two lines are redundant, drm_bridge_attach should do that.
> +
> + ret = drm_bridge_attach(encoder, bridge, NULL);
> + if (ret) {
> + drm_encoder_cleanup(encoder);
> + return NULL;
> + }
> +
> + DRM_DEBUG_DRIVER("Bridge encoder:%d created\n", encoder->base.id);
> +
> + return encoder;
> +}
> +
> /*
> * DRM_CONNECTOR
> */
> @@ -967,12 +1004,13 @@ static int ltdc_get_caps(struct drm_device *ddev)
> return 0;
> }
>
> -static struct drm_panel *ltdc_get_panel(struct drm_device *ddev)
> +static int ltdc_parse_dt(struct drm_device *ddev)
> {
> + struct ltdc_device *ldev = ddev->dev_private;
> struct device *dev = ddev->dev;
> struct device_node *np = dev->of_node;
> - struct device_node *entity, *port = NULL;
> - struct drm_panel *panel = NULL;
> + struct device_node *entity;
> + int ret;
>
> DRM_DEBUG_DRIVER("\n");
>
> @@ -985,21 +1023,13 @@ static struct drm_panel *ltdc_get_panel(struct drm_device *ddev)
> if (!of_device_is_available(entity))
> continue;
>
> - port = of_graph_get_remote_port_parent(entity);
> - if (port) {
> - panel = of_drm_find_panel(port);
> - of_node_put(port);
> - if (panel) {
> - DRM_DEBUG_DRIVER("remote panel %s\n",
> - port->full_name);
> - } else {
> - DRM_DEBUG_DRIVER("panel missing\n");
> - of_node_put(entity);
> - }
> - }
> + ret = drm_of_find_panel_or_bridge(np, 0, 0,
> + &ldev->panel, &ldev->bridge);
> + if (ret)
> + return ret;
> }
>
> - return panel;
> + return 0;
> }
>
> int ltdc_load(struct drm_device *ddev)
> @@ -1017,9 +1047,9 @@ int ltdc_load(struct drm_device *ddev)
>
> DRM_DEBUG_DRIVER("\n");
>
> - ldev->panel = ltdc_get_panel(ddev);
> - if (!ldev->panel)
> - return -EPROBE_DEFER;
> + ret = ltdc_parse_dt(ddev);
> + if (ret)
> + return ret;
>
> rstc = of_reset_control_get(np, NULL);
>
> @@ -1077,6 +1107,12 @@ int ltdc_load(struct drm_device *ddev)
>
> DRM_INFO("ltdc hw version 0x%08x - ready\n", ldev->caps.hw_version);
>
> + if (ldev->bridge) {
> + encoder = bridge_encoder_create(ddev, ldev->bridge);
> + if (!encoder)
> + return -EINVAL;
> + }
> +
I guess you could add 'else' clause after closing bracket - ldev->bridge
and ldev->panel are mutually exclusive, but it is up to you.
Beside this:
Reviewed-by: Andrzej Hajda <a.hajda at samsung.com>
Regards
Andrzej
> if (ldev->panel) {
> encoder = ltdc_rgb_encoder_create(ddev);
> if (!encoder) {
> diff --git a/drivers/gpu/drm/stm/ltdc.h b/drivers/gpu/drm/stm/ltdc.h
> index 5427ef4..0083cad 100644
> --- a/drivers/gpu/drm/stm/ltdc.h
> +++ b/drivers/gpu/drm/stm/ltdc.h
> @@ -25,6 +25,7 @@ struct ltdc_device {
> void __iomem *regs;
> struct clk *pixel_clk; /* lcd pixel clock */
> struct drm_panel *panel;
> + struct drm_bridge *bridge;
> struct spinlock lock; /* protecting irq status register */
> struct ltdc_caps caps;
> u32 clut[256]; /* color look up table */
More information about the linux-arm-kernel
mailing list