From patchwork Wed Jul 4 07:56:35 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sascha Hauer X-Patchwork-Id: 1154741 Return-Path: X-Original-To: patchwork-linux-fbdev@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 2EA8F3FE4F for ; Wed, 4 Jul 2012 07:56:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756117Ab2GDH4o (ORCPT ); Wed, 4 Jul 2012 03:56:44 -0400 Received: from metis.ext.pengutronix.de ([92.198.50.35]:59914 "EHLO metis.ext.pengutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755901Ab2GDH4n (ORCPT ); Wed, 4 Jul 2012 03:56:43 -0400 Received: from dude.hi.pengutronix.de ([2001:6f8:1178:2:21e:67ff:fe11:9c5c]) by metis.ext.pengutronix.de with esmtp (Exim 4.72) (envelope-from ) id 1SmKS0-0002X6-Kf; Wed, 04 Jul 2012 09:56:40 +0200 Received: from sha by dude.hi.pengutronix.de with local (Exim 4.80) (envelope-from ) id 1SmKRz-0007zM-IX; Wed, 04 Jul 2012 09:56:39 +0200 From: Sascha Hauer To: devicetree-discuss@lists.ozlabs.org Cc: linux-fbdev@vger.kernel.org, Grant Likely , Anatolij Gustschin , Laurent Pinchart , Mitch Bradley , dri-devel@lists.freedesktop.org, kernel@pengutronix.de, Sascha Hauer Subject: [PATCH v2] of: Add videomode helper Date: Wed, 4 Jul 2012 09:56:35 +0200 Message-Id: <1341388595-30672-1-git-send-email-s.hauer@pengutronix.de> X-Mailer: git-send-email 1.7.10 X-SA-Exim-Connect-IP: 2001:6f8:1178:2:21e:67ff:fe11:9c5c X-SA-Exim-Mail-From: sha@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-fbdev@vger.kernel.org Sender: linux-fbdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fbdev@vger.kernel.org This patch adds a helper function for parsing videomodes from the devicetree. The videomode can be either converted to a struct drm_display_mode or a struct fb_videomode. Signed-off-by: Sascha Hauer --- changes since v1: - use hyphens instead of underscores for property names .../devicetree/bindings/video/displaymode | 40 ++++++++ drivers/of/Kconfig | 5 + drivers/of/Makefile | 1 + drivers/of/of_videomode.c | 108 ++++++++++++++++++++ include/linux/of_videomode.h | 19 ++++ 5 files changed, 173 insertions(+) create mode 100644 Documentation/devicetree/bindings/video/displaymode create mode 100644 drivers/of/of_videomode.c create mode 100644 include/linux/of_videomode.h diff --git a/Documentation/devicetree/bindings/video/displaymode b/Documentation/devicetree/bindings/video/displaymode new file mode 100644 index 0000000..43cc17d --- /dev/null +++ b/Documentation/devicetree/bindings/video/displaymode @@ -0,0 +1,40 @@ +videomode bindings +================== + +Required properties: + - xres, yres: Display resolution + - left-margin, right-margin, hsync-len: Horizontal Display timing parameters + in pixels + upper-margin, lower-margin, vsync-len: Vertical display timing parameters in + lines + - clock: displayclock in Hz + +Optional properties: + - width-mm, height-mm: Display dimensions in mm + - hsync-active-high (bool): Hsync pulse is active high + - vsync-active-high (bool): Vsync pulse is active high + - interlaced (bool): This is an interlaced mode + - doublescan (bool): This is a doublescan mode + +There are different ways of describing a display mode. The devicetree representation +corresponds to the one used by the Linux Framebuffer framework described here in +Documentation/fb/framebuffer.txt. This representation has been chosen because it's +the only format which does not allow for inconsistent parameters.Unlike the Framebuffer +framework the devicetree has the clock in Hz instead of ps. + +Example: + + display@0 { + /* 1920x1080p24 */ + clock = <52000000>; + xres = <1920>; + yres = <1080>; + left-margin = <25>; + right-margin = <25>; + hsync-len = <25>; + lower-margin = <2>; + upper-margin = <2>; + vsync-len = <2>; + hsync-active-high; + }; + diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index dfba3e6..a3acaa3 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -83,4 +83,9 @@ config OF_MTD depends on MTD def_bool y +config OF_VIDEOMODE + def_bool y + help + helper to parse videomodes from the devicetree + endmenu # OF diff --git a/drivers/of/Makefile b/drivers/of/Makefile index e027f44..80e6db3 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_OF_MDIO) += of_mdio.o obj-$(CONFIG_OF_PCI) += of_pci.o obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o obj-$(CONFIG_OF_MTD) += of_mtd.o +obj-$(CONFIG_OF_VIDEOMODE) += of_videomode.o diff --git a/drivers/of/of_videomode.c b/drivers/of/of_videomode.c new file mode 100644 index 0000000..50d3bd2 --- /dev/null +++ b/drivers/of/of_videomode.c @@ -0,0 +1,108 @@ +/* + * OF helpers for parsing display modes + * + * Copyright (c) 2012 Sascha Hauer , Pengutronix + * + * This file is released under the GPLv2 + */ +#include +#include +#include +#include +#include + +int of_get_video_mode(struct device_node *np, struct drm_display_mode *dmode, + struct fb_videomode *fbmode) +{ + int ret = 0; + u32 left_margin, xres, right_margin, hsync_len; + u32 upper_margin, yres, lower_margin, vsync_len; + u32 width_mm = 0, height_mm = 0; + u32 clock; + bool hah = false, vah = false, interlaced = false, doublescan = false; + + if (!np) + return -EINVAL; + + ret |= of_property_read_u32(np, "left-margin", &left_margin); + ret |= of_property_read_u32(np, "xres", &xres); + ret |= of_property_read_u32(np, "right-margin", &right_margin); + ret |= of_property_read_u32(np, "hsync-len", &hsync_len); + ret |= of_property_read_u32(np, "upper-margin", &upper_margin); + ret |= of_property_read_u32(np, "yres", &yres); + ret |= of_property_read_u32(np, "lower-margin", &lower_margin); + ret |= of_property_read_u32(np, "vsync-len", &vsync_len); + ret |= of_property_read_u32(np, "clock", &clock); + if (ret) + return -EINVAL; + + of_property_read_u32(np, "width-mm", &width_mm); + of_property_read_u32(np, "height-mm", &height_mm); + + hah = of_property_read_bool(np, "hsync-active-high"); + vah = of_property_read_bool(np, "vsync-active-high"); + interlaced = of_property_read_bool(np, "interlaced"); + doublescan = of_property_read_bool(np, "doublescan"); + + if (dmode) { + memset(dmode, 0, sizeof(*dmode)); + + dmode->hdisplay = xres; + dmode->hsync_start = xres + right_margin; + dmode->hsync_end = xres + right_margin + hsync_len; + dmode->htotal = xres + right_margin + hsync_len + left_margin; + + dmode->vdisplay = yres; + dmode->vsync_start = yres + lower_margin; + dmode->vsync_end = yres + lower_margin + vsync_len; + dmode->vtotal = yres + lower_margin + vsync_len + upper_margin; + + dmode->width_mm = width_mm; + dmode->height_mm = height_mm; + + dmode->clock = clock / 1000; + + if (hah) + dmode->flags |= DRM_MODE_FLAG_PHSYNC; + else + dmode->flags |= DRM_MODE_FLAG_NHSYNC; + if (vah) + dmode->flags |= DRM_MODE_FLAG_PVSYNC; + else + dmode->flags |= DRM_MODE_FLAG_NVSYNC; + if (interlaced) + dmode->flags |= DRM_MODE_FLAG_INTERLACE; + if (doublescan) + dmode->flags |= DRM_MODE_FLAG_DBLSCAN; + + drm_mode_set_name(dmode); + } + + if (fbmode) { + memset(fbmode, 0, sizeof(*fbmode)); + + fbmode->xres = xres; + fbmode->left_margin = left_margin; + fbmode->right_margin = right_margin; + fbmode->hsync_len = hsync_len; + + fbmode->yres = yres; + fbmode->upper_margin = upper_margin; + fbmode->lower_margin = lower_margin; + fbmode->vsync_len = vsync_len; + + fbmode->pixclock = KHZ2PICOS(clock / 1000); + + if (hah) + fbmode->sync |= FB_SYNC_HOR_HIGH_ACT; + if (vah) + fbmode->sync |= FB_SYNC_VERT_HIGH_ACT; + if (interlaced) + fbmode->vmode |= FB_VMODE_INTERLACED; + if (doublescan) + fbmode->vmode |= FB_VMODE_DOUBLE; + } + + return 0; +} +EXPORT_SYMBOL_GPL(of_get_video_mode); diff --git a/include/linux/of_videomode.h b/include/linux/of_videomode.h new file mode 100644 index 0000000..a988429 --- /dev/null +++ b/include/linux/of_videomode.h @@ -0,0 +1,19 @@ +/* + * Copyright 2012 Sascha Hauer + * + * OF helpers for videomodes. + * + * This file is released under the GPLv2 + */ + +#ifndef __LINUX_OF_VIDEOMODE_H +#define __LINUX_OF_VIDEOMODE_H + +struct device_node; +struct fb_videomode; +struct drm_display_mode; + +int of_get_video_mode(struct device_node *np, struct drm_display_mode *dmode, + struct fb_videomode *fbmode); + +#endif /* __LINUX_OF_VIDEOMODE_H */