[RFC PATCH v3 5/5] drm/panel: simple: add panel-dpi support

Oleksandr Suvorov oleksandr.suvorov at toradex.com
Mon Feb 17 13:29:26 UTC 2020


On Sun, Feb 16, 2020 at 8:15 PM Sam Ravnborg <sam at ravnborg.org> wrote:
>
> RFC only - not tested yet!

I've just tested this patch on Apalis iMX6Q and Colibri iMX7D using
panel settings from the following patch:
https://lore.kernel.org/linux-arm-kernel/20200115123401.2264293-4-oleksandr.suvorov@toradex.com/

It works for me, thanks!

Reviewed-by: Oleksandr Suvorov <oleksandr.suvorov at toradex.com>

>
> The panel-dpi compatible is a fallback that
> allows the DT to specify the timing.
>
> When matching panel-dpi expect the device tree to include the
> timing information for the display-panel.
>
> Background for this change:
> There are a lot of panels and new models hits the market very often.
> It is a lost cause trying to chase them all and users of new panels
> will often find them in situations that the panel they ues are not
> supported by the kernel.
> On top of this a lot of panels are customized based on customer
> specifications.
>
> Including the panel timing in the device tree allows for a simple
> way to describe the actual HW and use this description in a generic
> way in the kernel.
> This allows uses of proprietary panels, or panels which are not
> included in the kernel, to specify the timing in the device tree
> together with all the other HW descriptions.
> And thus, using the device tree it is then easy to add support
> for an otherwise unknown panel.
>
> The current support expect panels that do not require any
> delays for prepare/enable/disable/unprepare.
>
> Signed-off-by: Sam Ravnborg <sam at ravnborg.org>
> Cc: Thierry Reding <thierry.reding at gmail.com>
> Cc: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> Cc: Maxime Ripard <mripard at kernel.org>
> Cc: Oleksandr Suvorov <oleksandr.suvorov at toradex.com>
> ---
>  drivers/gpu/drm/panel/panel-simple.c | 74 +++++++++++++++++++++++++++-
>  1 file changed, 72 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
> index 82363d05bad4..188526637398 100644
> --- a/drivers/gpu/drm/panel/panel-simple.c
> +++ b/drivers/gpu/drm/panel/panel-simple.c
> @@ -351,6 +351,65 @@ static const struct drm_panel_funcs panel_simple_funcs = {
>         .get_timings = panel_simple_get_timings,
>  };
>
> +static struct panel_desc panel_dpi;
> +
> +static int panel_dpi_probe(struct device *dev,
> +                          struct panel_simple *panel)
> +{
> +       struct display_timing *timing;
> +       const struct device_node *np;
> +       struct panel_desc *desc;
> +       unsigned int bus_flags;
> +       struct videomode vm;
> +       const char *mapping;
> +       int ret;
> +
> +       np = dev->of_node;
> +       desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
> +       if (!desc)
> +               return -ENOMEM;
> +
> +       timing = devm_kzalloc(dev, sizeof(*timing), GFP_KERNEL);
> +       if (!timing)
> +               return -ENOMEM;
> +
> +       ret = of_get_display_timing(np, "panel-timing", timing);
> +       if (ret < 0) {
> +               dev_err(dev, "%pOF: no panel-timing node found for \"panel-dpi\" binding\n",
> +                       np);
> +               return ret;
> +       }
> +
> +       desc->timings = timing;
> +       desc->num_timings = 1;
> +
> +       of_property_read_u32(np, "width-mm", &desc->size.width);
> +       of_property_read_u32(np, "height-mm", &desc->size.height);
> +
> +       of_property_read_string(np, "data-mapping", &mapping);
> +       if (!strcmp(mapping, "rgb24"))
> +               desc->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
> +       else if (!strcmp(mapping, "rgb565"))
> +               desc->bus_format = MEDIA_BUS_FMT_RGB565_1X16;
> +       else if (!strcmp(mapping, "bgr666"))
> +               desc->bus_format = MEDIA_BUS_FMT_RGB666_1X18;
> +       else if (!strcmp(mapping, "lvds666"))
> +               desc->bus_format = MEDIA_BUS_FMT_RGB666_1X24_CPADHI;
> +
> +       /* Extract bus_flags from display_timing */
> +       bus_flags = 0;
> +       vm.flags = timing->flags;
> +       drm_bus_flags_from_videomode(&vm, &bus_flags);
> +       desc->bus_flags = bus_flags;
> +
> +       /* We do not know the connector for the DT node, so guess it */
> +       desc->connector_type = DRM_MODE_CONNECTOR_DPI;
> +
> +       panel->desc = desc;
> +
> +       return 0;
> +}
> +
>  #define PANEL_SIMPLE_BOUNDS_CHECK(to_check, bounds, field) \
>         (to_check->field.typ >= bounds->field.min && \
>          to_check->field.typ <= bounds->field.max)
> @@ -437,8 +496,15 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
>                         return -EPROBE_DEFER;
>         }
>
> -       if (!of_get_display_timing(dev->of_node, "panel-timing", &dt))
> -               panel_simple_parse_panel_timing_node(dev, panel, &dt);
> +       if (desc == &panel_dpi) {
> +               /* Handle the generic panel-dpi binding */
> +               err = panel_dpi_probe(dev, panel);
> +               if (err)
> +                       goto free_ddc;
> +       } else {
> +               if (!of_get_display_timing(dev->of_node, "panel-timing", &dt))
> +                       panel_simple_parse_panel_timing_node(dev, panel, &dt);
> +       }
>
>         drm_panel_init(&panel->base, dev, &panel_simple_funcs,
>                        desc->connector_type);
> @@ -3688,6 +3754,10 @@ static const struct of_device_id platform_of_match[] = {
>         }, {
>                 .compatible = "winstar,wf35ltiacd",
>                 .data = &winstar_wf35ltiacd,
> +       }, {
> +               /* Must be the last entry */
> +               .compatible = "panel-dpi",
> +               .data = &panel_dpi,
>         }, {
>                 /* sentinel */
>         }
> --
> 2.20.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel



--
Best regards
Oleksandr Suvorov

Toradex AG
Altsagenstrasse 5 | 6048 Horw/Luzern | Switzerland | T: +41 41 500
4800 (main line)


More information about the dri-devel mailing list