[PATCH 1/3] video: add support for getting video mode from device tree

Grant Likely grant.likely at secretlab.ca
Sun Feb 28 17:30:33 EST 2010


Hi Anatolij,

[added cc: to devicetree-discuss at lists.ozlabs.org]

On Sat, Feb 27, 2010 at 2:58 PM, Anatolij Gustschin <agust at denx.de> wrote:
> Framebuffer drivers may want to get panel timing info
> from the device tree. This patch adds appropriate support.
> Subsequent patch for FSL DIU frame buffer driver makes use
> of this functionality.

I think this is moving in the right direction, but there needs to
debate & review over the binding before committing to anything.
Please write a patch that documents the new binding in
Documentation/powerpc/dts-bindings.  All new bindings should be
documented and reviewed on devicetree-discuss before merging any
drivers that use them into mainline.

>From what I can tell by reading your code, I suspect that the binding
you've designed will solve your immediate problem, but won't be able
to handle anything slightly more complex, but it also looks like the
binding has been designed to be generic, usable by any display device.

First off, I did a tiny amount of research, and I didn't find any
existing OpenFirmware bindings for describing video displays.
Otherwise, I'd suggest considering that.

>From the little bit that I know, it seems that for most video devices
(ie. PCs) the video card discovers the capabilities of the screen by
reading the monitor's EDID data.  However, in your particular case
embedded case, a fixed flat panel is attached, and there isn't any
EDID data provided.  Therefore, you need an alternate method of
describing the display capabilities.  Rather than designing something
entirely new, you may want to consider using the EDID data format
directly; or at least cover the same things that EDID describes.  The
downside to using EDID directly is that it is a packed binary format
that isn't parseable by mere mortals; but the data contained in it
seems about right.  The upside is the kernel already knows what to do
with EDID data.

Otherwise you risk designing something that won't be useful for
anything much outside of your own use case.  For example, the binding
I see from the code cannot handle a display with multiple output
modes.

Also, since you're now in the realm of describing a video display,
which is separate from the display controller, you should consider
describing the display in a separate device tree node.  Maybe
something like this...

video {
        compatible = "fsl,mpc5121-diu";
        display {
                compatible = "<vendor>,<model>";
                edid = [edid-data];
        };
};

Cheers,
g.

>
> Signed-off-by: Anatolij Gustschin <agust at denx.de>
> ---
>  drivers/video/Kconfig  |    5 +++
>  drivers/video/Makefile |    1 +
>  drivers/video/ofmode.c |   95 ++++++++++++++++++++++++++++++++++++++++++++++++
>  drivers/video/ofmode.h |    6 +++
>  4 files changed, 107 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/video/ofmode.c
>  create mode 100644 drivers/video/ofmode.h
>
> diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
> index 5a5c303..dc1beb0 100644
> --- a/drivers/video/Kconfig
> +++ b/drivers/video/Kconfig
> @@ -203,6 +203,11 @@ config FB_MACMODES
>        depends on FB
>        default n
>
> +config FB_OF_MODE
> +       tristate
> +       depends on FB && OF
> +       default n
> +
>  config FB_BACKLIGHT
>        bool
>        depends on FB
> diff --git a/drivers/video/Makefile b/drivers/video/Makefile
> index 4ecb30c..c4a912b 100644
> --- a/drivers/video/Makefile
> +++ b/drivers/video/Makefile
> @@ -26,6 +26,7 @@ obj-$(CONFIG_FB_SVGALIB)       += svgalib.o
>  obj-$(CONFIG_FB_MACMODES)      += macmodes.o
>  obj-$(CONFIG_FB_DDC)           += fb_ddc.o
>  obj-$(CONFIG_FB_DEFERRED_IO)   += fb_defio.o
> +obj-$(CONFIG_FB_OF_MODE)       += ofmode.o
>
>  # Hardware specific drivers go first
>  obj-$(CONFIG_FB_AMIGA)            += amifb.o c2p_planar.o
> diff --git a/drivers/video/ofmode.c b/drivers/video/ofmode.c
> new file mode 100644
> index 0000000..78caad1
> --- /dev/null
> +++ b/drivers/video/ofmode.c
> @@ -0,0 +1,95 @@
> +/*
> + * Get video mode settings from Flattened Device Tree.
> + *
> + * Copyright (C) 2010 DENX Software Engineering.
> + * Anatolij Gustschin <agust at denx.de>
> + *
> + * This file is subject to the terms and conditions of the GNU General
> + * Public License version 2. See the file COPYING in the main directory
> + * of this archive for more details.
> + */
> +
> +#include <linux/fb.h>
> +#include <linux/of.h>
> +
> +int __devinit of_get_video_mode(struct device_node *np,
> +                               struct fb_info *info)
> +{
> +       struct fb_videomode dt_mode;
> +       const u32 *prop;
> +       unsigned int len;
> +
> +       if (!np || !info)
> +               return -EINVAL;
> +
> +       prop = of_get_property(np, "width", &len);
> +       if (!prop || len != sizeof(u32))
> +               goto err;
> +       dt_mode.xres = *prop;
> +
> +       prop = of_get_property(np, "height", &len);
> +       if (!prop || len != sizeof(u32))
> +               goto err;
> +       dt_mode.yres = *prop;
> +
> +       prop = of_get_property(np, "depth", &len);
> +       if (!prop || len != sizeof(u32))
> +               goto err;
> +       info->var.bits_per_pixel = *prop;
> +
> +       prop = of_get_property(np, "linebytes", &len);
> +       if (!prop || len != sizeof(u32))
> +               goto err;
> +       info->fix.line_length = *prop;
> +
> +       prop = of_get_property(np, "refresh", &len);
> +       if (prop && len == sizeof(u32))
> +               dt_mode.refresh = *prop; /* optional */
> +
> +       prop = of_get_property(np, "pixclock", &len);
> +       if (!prop || len != sizeof(u32))
> +               goto err;
> +       dt_mode.pixclock = *prop;
> +
> +       prop = of_get_property(np, "left_margin", &len);
> +       if (!prop || len != sizeof(u32))
> +               goto err;
> +       dt_mode.left_margin = *prop;
> +
> +       prop = of_get_property(np, "right_margin", &len);
> +       if (!prop || len != sizeof(u32))
> +               goto err;
> +       dt_mode.right_margin = *prop;
> +
> +       prop = of_get_property(np, "upper_margin", &len);
> +       if (!prop || len != sizeof(u32))
> +               goto err;
> +       dt_mode.upper_margin = *prop;
> +
> +       prop = of_get_property(np, "lower_margin", &len);
> +       if (!prop || len != sizeof(u32))
> +               goto err;
> +       dt_mode.lower_margin = *prop;
> +
> +       prop = of_get_property(np, "hsync_len", &len);
> +       if (!prop || len != sizeof(u32))
> +               goto err;
> +       dt_mode.hsync_len = *prop;
> +
> +       prop = of_get_property(np, "vsync_len", &len);
> +       if (!prop || len != sizeof(u32))
> +               goto err;
> +       dt_mode.vsync_len = *prop;
> +
> +       prop = of_get_property(np, "sync", &len);
> +       if (!prop || len != sizeof(u32))
> +               goto err;
> +       dt_mode.sync = *prop;
> +
> +       fb_videomode_to_var(&info->var, &dt_mode);
> +
> +       return 0;
> +err:
> +       pr_err("%s: Can't find expected mode entry\n", np->full_name);
> +       return -EINVAL;
> +}
> diff --git a/drivers/video/ofmode.h b/drivers/video/ofmode.h
> new file mode 100644
> index 0000000..9a13bec
> --- /dev/null
> +++ b/drivers/video/ofmode.h
> @@ -0,0 +1,6 @@
> +#ifndef _OFMODE_H
> +#define _OFMODE_H
> +
> +extern int __devinit of_get_video_mode(struct device_node *np,
> +                                       struct fb_info *info);
> +#endif
> --
> 1.6.3.3
>
>



-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.


More information about the Linuxppc-dev mailing list