Linux Framebuffer Layer development
 help / color / mirror / Atom feed
* [PATCH 5/5] OMAP: remove vram allocator
From: Tomi Valkeinen @ 2012-11-12 10:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1352715906-16946-1-git-send-email-tomi.valkeinen@ti.com>

OMAP specific vram allocator is no longer in use, and we can remove all
the vram code.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 arch/arm/plat-omap/include/plat/vram.h |   43 ---
 drivers/video/omap2/Kconfig            |    3 -
 drivers/video/omap2/Makefile           |    1 -
 drivers/video/omap2/dss/Kconfig        |   12 -
 drivers/video/omap2/vram.c             |  514 --------------------------------
 5 files changed, 573 deletions(-)
 delete mode 100644 arch/arm/plat-omap/include/plat/vram.h
 delete mode 100644 drivers/video/omap2/vram.c

diff --git a/arch/arm/plat-omap/include/plat/vram.h b/arch/arm/plat-omap/include/plat/vram.h
deleted file mode 100644
index 4d65b7d..0000000
--- a/arch/arm/plat-omap/include/plat/vram.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * VRAM manager for OMAP
- *
- * Copyright (C) 2009 Nokia Corporation
- * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#ifndef __OMAP_VRAM_H__
-#define __OMAP_VRAM_H__
-
-#include <linux/types.h>
-
-extern int omap_vram_add_region(unsigned long paddr, size_t size);
-extern int omap_vram_free(unsigned long paddr, size_t size);
-extern int omap_vram_alloc(size_t size, unsigned long *paddr);
-extern int omap_vram_reserve(unsigned long paddr, size_t size);
-extern void omap_vram_get_info(unsigned long *vram, unsigned long *free_vram,
-		unsigned long *largest_free_block);
-
-#ifdef CONFIG_OMAP2_VRAM
-extern void omap_vram_set_sdram_vram(u32 size, u32 start);
-
-extern void omap_vram_reserve_sdram_memblock(void);
-#else
-static inline void omap_vram_set_sdram_vram(u32 size, u32 start) { }
-
-static inline void omap_vram_reserve_sdram_memblock(void) { }
-#endif
-
-#endif
diff --git a/drivers/video/omap2/Kconfig b/drivers/video/omap2/Kconfig
index d877c36..346d67d 100644
--- a/drivers/video/omap2/Kconfig
+++ b/drivers/video/omap2/Kconfig
@@ -1,6 +1,3 @@
-config OMAP2_VRAM
-	bool
-
 config OMAP2_VRFB
 	bool
 
diff --git a/drivers/video/omap2/Makefile b/drivers/video/omap2/Makefile
index 5ddef12..5ea7cb9 100644
--- a/drivers/video/omap2/Makefile
+++ b/drivers/video/omap2/Makefile
@@ -1,4 +1,3 @@
-obj-$(CONFIG_OMAP2_VRAM) += vram.o
 obj-$(CONFIG_OMAP2_VRFB) += vrfb.o
 
 obj-$(CONFIG_OMAP2_DSS) += dss/
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
index 80f5390..058a669 100644
--- a/drivers/video/omap2/dss/Kconfig
+++ b/drivers/video/omap2/dss/Kconfig
@@ -6,18 +6,6 @@ menuconfig OMAP2_DSS
 
 if OMAP2_DSS
 
-config OMAP2_VRAM_SIZE
-	int "VRAM size (MB)"
-	range 0 32
-	default 0
-	help
-	  The amount of SDRAM to reserve at boot time for video RAM use.
-	  This VRAM will be used by omapfb and other drivers that need
-	  large continuous RAM area for video use.
-
-	  You can also set this with "vram=<bytes>" kernel argument, or
-	  in the board file.
-
 config OMAP2_DSS_DEBUG_SUPPORT
         bool "Debug support"
 	default y
diff --git a/drivers/video/omap2/vram.c b/drivers/video/omap2/vram.c
deleted file mode 100644
index f2b15c4..0000000
--- a/drivers/video/omap2/vram.c
+++ /dev/null
@@ -1,514 +0,0 @@
-/*
- * VRAM manager for OMAP
- *
- * Copyright (C) 2009 Nokia Corporation
- * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-/*#define DEBUG*/
-
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-#include <linux/seq_file.h>
-#include <linux/memblock.h>
-#include <linux/completion.h>
-#include <linux/debugfs.h>
-#include <linux/jiffies.h>
-#include <linux/module.h>
-
-#include <asm/setup.h>
-
-#include <plat/vram.h>
-
-#ifdef DEBUG
-#define DBG(format, ...) pr_debug("VRAM: " format, ## __VA_ARGS__)
-#else
-#define DBG(format, ...)
-#endif
-
-/* postponed regions are used to temporarily store region information at boot
- * time when we cannot yet allocate the region list */
-#define MAX_POSTPONED_REGIONS 10
-
-static bool vram_initialized;
-static int postponed_cnt;
-static struct {
-	unsigned long paddr;
-	size_t size;
-} postponed_regions[MAX_POSTPONED_REGIONS];
-
-struct vram_alloc {
-	struct list_head list;
-	unsigned long paddr;
-	unsigned pages;
-};
-
-struct vram_region {
-	struct list_head list;
-	struct list_head alloc_list;
-	unsigned long paddr;
-	unsigned pages;
-};
-
-static DEFINE_MUTEX(region_mutex);
-static LIST_HEAD(region_list);
-
-static struct vram_region *omap_vram_create_region(unsigned long paddr,
-		unsigned pages)
-{
-	struct vram_region *rm;
-
-	rm = kzalloc(sizeof(*rm), GFP_KERNEL);
-
-	if (rm) {
-		INIT_LIST_HEAD(&rm->alloc_list);
-		rm->paddr = paddr;
-		rm->pages = pages;
-	}
-
-	return rm;
-}
-
-#if 0
-static void omap_vram_free_region(struct vram_region *vr)
-{
-	list_del(&vr->list);
-	kfree(vr);
-}
-#endif
-
-static struct vram_alloc *omap_vram_create_allocation(struct vram_region *vr,
-		unsigned long paddr, unsigned pages)
-{
-	struct vram_alloc *va;
-	struct vram_alloc *new;
-
-	new = kzalloc(sizeof(*va), GFP_KERNEL);
-
-	if (!new)
-		return NULL;
-
-	new->paddr = paddr;
-	new->pages = pages;
-
-	list_for_each_entry(va, &vr->alloc_list, list) {
-		if (va->paddr > new->paddr)
-			break;
-	}
-
-	list_add_tail(&new->list, &va->list);
-
-	return new;
-}
-
-static void omap_vram_free_allocation(struct vram_alloc *va)
-{
-	list_del(&va->list);
-	kfree(va);
-}
-
-int omap_vram_add_region(unsigned long paddr, size_t size)
-{
-	struct vram_region *rm;
-	unsigned pages;
-
-	if (vram_initialized) {
-		DBG("adding region paddr %08lx size %d\n",
-				paddr, size);
-
-		size &= PAGE_MASK;
-		pages = size >> PAGE_SHIFT;
-
-		rm = omap_vram_create_region(paddr, pages);
-		if (rm = NULL)
-			return -ENOMEM;
-
-		list_add(&rm->list, &region_list);
-	} else {
-		if (postponed_cnt = MAX_POSTPONED_REGIONS)
-			return -ENOMEM;
-
-		postponed_regions[postponed_cnt].paddr = paddr;
-		postponed_regions[postponed_cnt].size = size;
-
-		++postponed_cnt;
-	}
-	return 0;
-}
-
-int omap_vram_free(unsigned long paddr, size_t size)
-{
-	struct vram_region *rm;
-	struct vram_alloc *alloc;
-	unsigned start, end;
-
-	DBG("free mem paddr %08lx size %d\n", paddr, size);
-
-	size = PAGE_ALIGN(size);
-
-	mutex_lock(&region_mutex);
-
-	list_for_each_entry(rm, &region_list, list) {
-		list_for_each_entry(alloc, &rm->alloc_list, list) {
-			start = alloc->paddr;
-			end = alloc->paddr + (alloc->pages >> PAGE_SHIFT);
-
-			if (start >= paddr && end < paddr + size)
-				goto found;
-		}
-	}
-
-	mutex_unlock(&region_mutex);
-	return -EINVAL;
-
-found:
-	omap_vram_free_allocation(alloc);
-
-	mutex_unlock(&region_mutex);
-	return 0;
-}
-EXPORT_SYMBOL(omap_vram_free);
-
-static int _omap_vram_reserve(unsigned long paddr, unsigned pages)
-{
-	struct vram_region *rm;
-	struct vram_alloc *alloc;
-	size_t size;
-
-	size = pages << PAGE_SHIFT;
-
-	list_for_each_entry(rm, &region_list, list) {
-		unsigned long start, end;
-
-		DBG("checking region %lx %d\n", rm->paddr, rm->pages);
-
-		start = rm->paddr;
-		end = start + (rm->pages << PAGE_SHIFT) - 1;
-		if (start > paddr || end < paddr + size - 1)
-			continue;
-
-		DBG("block ok, checking allocs\n");
-
-		list_for_each_entry(alloc, &rm->alloc_list, list) {
-			end = alloc->paddr - 1;
-
-			if (start <= paddr && end >= paddr + size - 1)
-				goto found;
-
-			start = alloc->paddr + (alloc->pages << PAGE_SHIFT);
-		}
-
-		end = rm->paddr + (rm->pages << PAGE_SHIFT) - 1;
-
-		if (!(start <= paddr && end >= paddr + size - 1))
-			continue;
-found:
-		DBG("found area start %lx, end %lx\n", start, end);
-
-		if (omap_vram_create_allocation(rm, paddr, pages) = NULL)
-			return -ENOMEM;
-
-		return 0;
-	}
-
-	return -ENOMEM;
-}
-
-int omap_vram_reserve(unsigned long paddr, size_t size)
-{
-	unsigned pages;
-	int r;
-
-	DBG("reserve mem paddr %08lx size %d\n", paddr, size);
-
-	size = PAGE_ALIGN(size);
-	pages = size >> PAGE_SHIFT;
-
-	mutex_lock(&region_mutex);
-
-	r = _omap_vram_reserve(paddr, pages);
-
-	mutex_unlock(&region_mutex);
-
-	return r;
-}
-EXPORT_SYMBOL(omap_vram_reserve);
-
-static int _omap_vram_alloc(unsigned pages, unsigned long *paddr)
-{
-	struct vram_region *rm;
-	struct vram_alloc *alloc;
-
-	list_for_each_entry(rm, &region_list, list) {
-		unsigned long start, end;
-
-		DBG("checking region %lx %d\n", rm->paddr, rm->pages);
-
-		start = rm->paddr;
-
-		list_for_each_entry(alloc, &rm->alloc_list, list) {
-			end = alloc->paddr;
-
-			if (end - start >= pages << PAGE_SHIFT)
-				goto found;
-
-			start = alloc->paddr + (alloc->pages << PAGE_SHIFT);
-		}
-
-		end = rm->paddr + (rm->pages << PAGE_SHIFT);
-found:
-		if (end - start < pages << PAGE_SHIFT)
-			continue;
-
-		DBG("found %lx, end %lx\n", start, end);
-
-		alloc = omap_vram_create_allocation(rm, start, pages);
-		if (alloc = NULL)
-			return -ENOMEM;
-
-		*paddr = start;
-
-		return 0;
-	}
-
-	return -ENOMEM;
-}
-
-int omap_vram_alloc(size_t size, unsigned long *paddr)
-{
-	unsigned pages;
-	int r;
-
-	BUG_ON(!size);
-
-	DBG("alloc mem size %d\n", size);
-
-	size = PAGE_ALIGN(size);
-	pages = size >> PAGE_SHIFT;
-
-	mutex_lock(&region_mutex);
-
-	r = _omap_vram_alloc(pages, paddr);
-
-	mutex_unlock(&region_mutex);
-
-	return r;
-}
-EXPORT_SYMBOL(omap_vram_alloc);
-
-void omap_vram_get_info(unsigned long *vram,
-		unsigned long *free_vram,
-		unsigned long *largest_free_block)
-{
-	struct vram_region *vr;
-	struct vram_alloc *va;
-
-	*vram = 0;
-	*free_vram = 0;
-	*largest_free_block = 0;
-
-	mutex_lock(&region_mutex);
-
-	list_for_each_entry(vr, &region_list, list) {
-		unsigned free;
-		unsigned long pa;
-
-		pa = vr->paddr;
-		*vram += vr->pages << PAGE_SHIFT;
-
-		list_for_each_entry(va, &vr->alloc_list, list) {
-			free = va->paddr - pa;
-			*free_vram += free;
-			if (free > *largest_free_block)
-				*largest_free_block = free;
-			pa = va->paddr + (va->pages << PAGE_SHIFT);
-		}
-
-		free = vr->paddr + (vr->pages << PAGE_SHIFT) - pa;
-		*free_vram += free;
-		if (free > *largest_free_block)
-			*largest_free_block = free;
-	}
-
-	mutex_unlock(&region_mutex);
-}
-EXPORT_SYMBOL(omap_vram_get_info);
-
-#if defined(CONFIG_DEBUG_FS)
-static int vram_debug_show(struct seq_file *s, void *unused)
-{
-	struct vram_region *vr;
-	struct vram_alloc *va;
-	unsigned size;
-
-	mutex_lock(&region_mutex);
-
-	list_for_each_entry(vr, &region_list, list) {
-		size = vr->pages << PAGE_SHIFT;
-		seq_printf(s, "%08lx-%08lx (%d bytes)\n",
-				vr->paddr, vr->paddr + size - 1,
-				size);
-
-		list_for_each_entry(va, &vr->alloc_list, list) {
-			size = va->pages << PAGE_SHIFT;
-			seq_printf(s, "    %08lx-%08lx (%d bytes)\n",
-					va->paddr, va->paddr + size - 1,
-					size);
-		}
-	}
-
-	mutex_unlock(&region_mutex);
-
-	return 0;
-}
-
-static int vram_debug_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, vram_debug_show, inode->i_private);
-}
-
-static const struct file_operations vram_debug_fops = {
-	.open           = vram_debug_open,
-	.read           = seq_read,
-	.llseek         = seq_lseek,
-	.release        = single_release,
-};
-
-static int __init omap_vram_create_debugfs(void)
-{
-	struct dentry *d;
-
-	d = debugfs_create_file("vram", S_IRUGO, NULL,
-			NULL, &vram_debug_fops);
-	if (IS_ERR(d))
-		return PTR_ERR(d);
-
-	return 0;
-}
-#endif
-
-static __init int omap_vram_init(void)
-{
-	int i;
-
-	vram_initialized = 1;
-
-	for (i = 0; i < postponed_cnt; i++)
-		omap_vram_add_region(postponed_regions[i].paddr,
-				postponed_regions[i].size);
-
-#ifdef CONFIG_DEBUG_FS
-	if (omap_vram_create_debugfs())
-		pr_err("VRAM: Failed to create debugfs file\n");
-#endif
-
-	return 0;
-}
-
-arch_initcall(omap_vram_init);
-
-/* boottime vram alloc stuff */
-
-/* set from board file */
-static u32 omap_vram_sdram_start __initdata;
-static u32 omap_vram_sdram_size __initdata;
-
-/* set from kernel cmdline */
-static u32 omap_vram_def_sdram_size __initdata;
-static u32 omap_vram_def_sdram_start __initdata;
-
-static int __init omap_vram_early_vram(char *p)
-{
-	omap_vram_def_sdram_size = memparse(p, &p);
-	if (*p = ',')
-		omap_vram_def_sdram_start = simple_strtoul(p + 1, &p, 16);
-	return 0;
-}
-early_param("vram", omap_vram_early_vram);
-
-/*
- * Called from map_io. We need to call to this early enough so that we
- * can reserve the fixed SDRAM regions before VM could get hold of them.
- */
-void __init omap_vram_reserve_sdram_memblock(void)
-{
-	u32 paddr;
-	u32 size = 0;
-
-	/* cmdline arg overrides the board file definition */
-	if (omap_vram_def_sdram_size) {
-		size = omap_vram_def_sdram_size;
-		paddr = omap_vram_def_sdram_start;
-	}
-
-	if (!size) {
-		size = omap_vram_sdram_size;
-		paddr = omap_vram_sdram_start;
-	}
-
-#ifdef CONFIG_OMAP2_VRAM_SIZE
-	if (!size) {
-		size = CONFIG_OMAP2_VRAM_SIZE * 1024 * 1024;
-		paddr = 0;
-	}
-#endif
-
-	if (!size)
-		return;
-
-	size = ALIGN(size, SZ_2M);
-
-	if (paddr) {
-		if (paddr & ~PAGE_MASK) {
-			pr_err("VRAM start address 0x%08x not page aligned\n",
-					paddr);
-			return;
-		}
-
-		if (!memblock_is_region_memory(paddr, size)) {
-			pr_err("Illegal SDRAM region 0x%08x..0x%08x for VRAM\n",
-					paddr, paddr + size - 1);
-			return;
-		}
-
-		if (memblock_is_region_reserved(paddr, size)) {
-			pr_err("FB: failed to reserve VRAM - busy\n");
-			return;
-		}
-
-		if (memblock_reserve(paddr, size) < 0) {
-			pr_err("FB: failed to reserve VRAM - no memory\n");
-			return;
-		}
-	} else {
-		paddr = memblock_alloc(size, SZ_2M);
-	}
-
-	memblock_free(paddr, size);
-	memblock_remove(paddr, size);
-
-	omap_vram_add_region(paddr, size);
-
-	pr_info("Reserving %u bytes SDRAM for VRAM\n", size);
-}
-
-void __init omap_vram_set_sdram_vram(u32 size, u32 start)
-{
-	omap_vram_sdram_start = start;
-	omap_vram_sdram_size = size;
-}
-- 
1.7.10.4


^ permalink raw reply related

* [patch] fbmem: return -EFAULT on copy_to_user() failure
From: Dan Carpenter @ 2012-11-12 11:08 UTC (permalink / raw)
  To: Florian Tobias Schandinat; +Cc: linux-fbdev, linux-kernel, kernel-janitors

copy_to_user() returns the number of bytes remaining to be copied.
put_user() returns -EFAULT on error.

This function ORs a bunch of stuff together and returns jumbled non-zero
values on error.  It should return -EFAULT.

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>

diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 3ff0105..3d2a4d0 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1302,8 +1302,9 @@ static int do_fscreeninfo_to_user(struct fb_fix_screeninfo *fix,
 	err |= put_user(fix->accel, &fix32->accel);
 	err |= copy_to_user(fix32->reserved, fix->reserved,
 			    sizeof(fix->reserved));
-
-	return err;
+	if (err)
+		return -EFAULT;
+	return 0;
 }
 
 static int fb_get_fscreeninfo(struct fb_info *info, unsigned int cmd,

^ permalink raw reply related

* Re: [PATCH v7 5/8] fbmon: add videomode helpers
From: Laurent Pinchart @ 2012-11-12 11:46 UTC (permalink / raw)
  To: Steffen Trumtrar
  Cc: Manjunathappa, Prakash, linux-fbdev@vger.kernel.org,
	devicetree-discuss@lists.ozlabs.org,
	dri-devel@lists.freedesktop.org, Valkeinen, Tomi,
	kernel@pengutronix.de, Guennady Liakhovetski,
	linux-media@vger.kernel.org
In-Reply-To: <20121109193133.GD3660@pengutronix.de>

Hi Steffen,

On Friday 09 November 2012 20:31:33 Steffen Trumtrar wrote:
> On Fri, Nov 09, 2012 at 04:54:16PM +0000, Manjunathappa, Prakash wrote:
> > On Fri, Nov 09, 2012 at 02:55:45, Steffen Trumtrar wrote:
> > > On Wed, Oct 31, 2012 at 03:30:03PM +0000, Manjunathappa, Prakash wrote:
> > > > On Wed, Oct 31, 2012 at 14:58:05, Steffen Trumtrar wrote:
> > > > > +#if IS_ENABLED(CONFIG_VIDEOMODE)
> > > > > +int videomode_to_fb_videomode(struct videomode *vm, struct
> > > > > fb_videomode *fbmode) +{
> > > > > +	fbmode->xres = vm->hactive;
> > > > > +	fbmode->left_margin = vm->hback_porch;
> > > > > +	fbmode->right_margin = vm->hfront_porch;
> > > > > +	fbmode->hsync_len = vm->hsync_len;
> > > > > +
> > > > > +	fbmode->yres = vm->vactive;
> > > > > +	fbmode->upper_margin = vm->vback_porch;
> > > > > +	fbmode->lower_margin = vm->vfront_porch;
> > > > > +	fbmode->vsync_len = vm->vsync_len;
> > > > > +
> > > > > +	fbmode->pixclock = KHZ2PICOS(vm->pixelclock / 1000);
> > > > > +
> > > > > +	fbmode->sync = 0;
> > > > > +	fbmode->vmode = 0;
> > > > > +	if (vm->hah)
> > > > > +		fbmode->sync |= FB_SYNC_HOR_HIGH_ACT;
> > > > > +	if (vm->vah)
> > > > > +		fbmode->sync |= FB_SYNC_VERT_HIGH_ACT;
> > > > > +	if (vm->interlaced)
> > > > > +		fbmode->vmode |= FB_VMODE_INTERLACED;
> > > > > +	if (vm->doublescan)
> > > > > +		fbmode->vmode |= FB_VMODE_DOUBLE;
> > > > > +
> > > > 
> > > > "pixelclk-inverted" property of the panel is not percolated
> > > > fb_videomode.
> > > > Please let me know if I am missing something.
> > > 
> > > The next version is almost finished. Only thing I'm missing is this.
> > > And I actually do not know which flag would represent an inverted
> > > pixelclock in fb_videomode. Does anybody have any idea what I have to
> > > do here?> > 
> > > 	if (vm->pixelclk_pol)
> > > 	
> > > 		fbmode->sync = ???
> > > 
> > > That's as far as I have come and I don't see a flag that seems right.
> > > Is this even a valid property of fb_videomode?
> > 
> > Thanks for considering it, I see IMX addresses it as proprietary FB_SYNC_
> > flag. FB_SYNC_CLK_INVERT: arch/arm/plat-mxc/include/mach/mx3fb.h
> 
> No problem. So, it seems this flag has to be set in some imx-specific
> videomode_to_fb_videomode function. It is included in the
> struct videomode, so that should be no problem. But it will not be
> part of this series.

A possible solution would be to standardize the FB_SYNC_CLK_INVERT flag in 
fbdev, but that's in my opinion out of scope of this patch series. iMX3 
developers, feel free to send patches :-)

-- 
Regards,

Laurent Pinchart


^ permalink raw reply

* Re: [PATCH 0/3] OMAPDSS: DISPC: Writeback fixes
From: Tomi Valkeinen @ 2012-11-12 12:00 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-fbdev, linux-omap
In-Reply-To: <1352268905-31093-1-git-send-email-archit@ti.com>

[-- Attachment #1: Type: text/plain, Size: 753 bytes --]

On 2012-11-07 08:15, Archit Taneja wrote:
> Some issues were found in the DISPC driver when performing scaling with
> writeback pipeline. This series fixes those issues.
> 
> Reference tree:
> git://gitorious.org/~boddob/linux-omap-dss2/archit-dss2-clone.git 3.8/writeback_fixes_dispc
> 
> Archit Taneja (3):
>   OMAPDSS: DISPC: Fix calc_scaling_44xx() bugs for writeback pipeline
>   OMAPDSS: DISPC: Don't allow predecimation for writeback
>   OMAPDSS: DISPC: Use output width and height to calculate row/pix inc
>     for writeback
> 
>  drivers/video/omap2/dss/dispc.c |   39 +++++++++++++++++++++++++++------------
>  1 file changed, 27 insertions(+), 12 deletions(-)
> 

Thanks, looks ok. I'll apply to omapdss tree.

 Tomi



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 897 bytes --]

^ permalink raw reply

* Re: [PATCH 0/3] OMAPDSS: APPLY: Misc Fixes
From: Tomi Valkeinen @ 2012-11-12 12:00 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-fbdev, linux-omap
In-Reply-To: <1352279844-10494-1-git-send-email-archit@ti.com>

[-- Attachment #1: Type: text/plain, Size: 782 bytes --]

On 2012-11-07 11:17, Archit Taneja wrote:
> This series resolves a few minor issues with APPLY. Tested on a 4430sdp, checked
> switching overlays between DSI command mode and HDMI displays for any unexpected
> behavior.
> 
> Reference tree:
> git://gitorious.org/~boddob/linux-omap-dss2/archit-dss2-clone.git 3.8/apply_fixes
> 
> Archit Taneja (3):
>   OMAPDSS: APPLY: Don't treat an overlay's channel out as shadow bits
>   OMAPDSS: APPLY: Remove unnecessary variable in dss_apply_irq_handler
>   OMAPDSS: APPLY: Remove unnecessary call to mg_clear_shadow_dirty
> 
>  drivers/video/omap2/dss/apply.c |   48 +++++++++++++++++++++------------------
>  1 file changed, 26 insertions(+), 22 deletions(-)
> 

Thanks, looks ok. I'll apply to omapdss tree.

 Tomi



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 897 bytes --]

^ permalink raw reply

* Re: [PATCH 0/2] Adding devm_ functions and DT support to MIPI driver
From: Tomi Valkeinen @ 2012-11-12 12:35 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1352547285-12302-1-git-send-email-shaik.ameer@samsung.com>

Hi,

On 2012-11-10 13:34, Shaik Ameer Basha wrote:
> In this patch series,
> 
> First patch adds the devm_ functions to the driver code for automatic
> code cleanup.
> 
> Second patch adds the DT support for the exynos mipi-dsi driver.
> for DT support, mipi device node should supply the following
> information to the mipi-dsi driver.
> 1] dsim_config information
> 2] d-phy setting information
> 3] lcd poweron, reset information
> 4] fb_videomode information
> 
> refer the documentation files for further details.
> 
> Shaik Ameer Basha (2):
>   exynos-mipi-dsi: using devm_ functions for automatic cleanup
>   video: exynos-mipi-dsi: Adding DT support to exynos mipi driver

MIPI is an organization. DSI is a protocol from MIPI. MIPI has many
protocols. Thus it doesn't make sense to say "MIPI driver", "MIPI
display", or use names like "samsung,exynos-mipi".

It's either "MIPI DSI" if you want to be exact, or just "DSI", which I
think is clear from the context.

What is "dsim"?

 Tomi



^ permalink raw reply

* Re: [PATCH 0/2] Adding devm_ functions and DT support to MIPI driver
From: Sylwester Nawrocki @ 2012-11-12 13:08 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1352547285-12302-1-git-send-email-shaik.ameer@samsung.com>

Hi,

On 11/12/2012 01:35 PM, Tomi Valkeinen wrote:
>> Shaik Ameer Basha (2):
>>   exynos-mipi-dsi: using devm_ functions for automatic cleanup
>>   video: exynos-mipi-dsi: Adding DT support to exynos mipi driver
> 
> MIPI is an organization. DSI is a protocol from MIPI. MIPI has many
> protocols. Thus it doesn't make sense to say "MIPI driver", "MIPI
> display", or use names like "samsung,exynos-mipi".

True.

> It's either "MIPI DSI" if you want to be exact, or just "DSI", which I
> think is clear from the context.
> 
> What is "dsim"?

In the Samsung SoCs documentation MIPI DSIM stands for MIPI DSI Master
and similarly MIPI CSIS stands for MIPI CSI Slave.

-- 

Regards,
Sylwester

^ permalink raw reply

* Re: [PATCH 0/5] OMAPFB: use dma_alloc instead of omap's vram
From: Grazvydas Ignotas @ 2012-11-12 13:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1352715906-16946-1-git-send-email-tomi.valkeinen@ti.com>

Hi,

On Mon, Nov 12, 2012 at 12:25 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> This series changes omapfb to use standard dma_alloc funcs instead of omap
> specific vram allocator. This let's us remove the omap vram allocator, making
> omapfb platform independent.
>
> However, note that using standard dma funcs causes the following downsides:
>
> ...
>
> 3) OMAPFB_GET_VRAM_INFO ioctl cannot return real values anymore. I
> changed the ioctl to return 64M for all the values, which, I hope, the
> applications will interpret as "there's enough vram".

Do at least OMAPFB_QUERY_MEM/OMAPFB_SETUP_MEM still work?

> 4) "vram" kernel parameter to define how much ram to reserve for video use no
> longer works. The user needs to enable CMA and use "cma" parameter.

That's a significant change, you should update Documentation/ .
What about omapfb.vram, is it still there?
Perhaps we also need to select/depend on CMA?


-- 
Gražvydas

^ permalink raw reply

* Re: [PATCH 0/5] OMAPFB: use dma_alloc instead of omap's vram
From: Tomi Valkeinen @ 2012-11-12 13:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CANOLnOO0yMabku-_3yhi=1bwohbrb=rtFDOuKf1LPCAFv_OqCQ@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1308 bytes --]

On 2012-11-12 15:39, Grazvydas Ignotas wrote:
> Hi,
> 
> On Mon, Nov 12, 2012 at 12:25 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
>> This series changes omapfb to use standard dma_alloc funcs instead of omap
>> specific vram allocator. This let's us remove the omap vram allocator, making
>> omapfb platform independent.
>>
>> However, note that using standard dma funcs causes the following downsides:
>>
>> ...
>>
>> 3) OMAPFB_GET_VRAM_INFO ioctl cannot return real values anymore. I
>> changed the ioctl to return 64M for all the values, which, I hope, the
>> applications will interpret as "there's enough vram".
> 
> Do at least OMAPFB_QUERY_MEM/OMAPFB_SETUP_MEM still work?

Yes.

>> 4) "vram" kernel parameter to define how much ram to reserve for video use no
>> longer works. The user needs to enable CMA and use "cma" parameter.
> 
> That's a significant change, you should update Documentation/ .

Ah right. The documentation. I never remember =).

> What about omapfb.vram, is it still there?

Yes.

> Perhaps we also need to select/depend on CMA?

dma_alloc_* funcs work fine without CMA. CMA only makes them work
better. Thus I don't think OMAPFB should depend on CMA, but perhaps CMA
should be enabled by default in omap2plus_defconfig?

 Tomi



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 897 bytes --]

^ permalink raw reply

* Re: [PATCH 0/5] OMAPFB: use dma_alloc instead of omap's vram
From: Tomi Valkeinen @ 2012-11-12 13:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CANOLnOO0yMabku-_3yhi=1bwohbrb=rtFDOuKf1LPCAFv_OqCQ@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 2064 bytes --]

On 2012-11-12 15:39, Grazvydas Ignotas wrote:
> Hi,
> 
> On Mon, Nov 12, 2012 at 12:25 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
>> This series changes omapfb to use standard dma_alloc funcs instead of omap
>> specific vram allocator. This let's us remove the omap vram allocator, making
>> omapfb platform independent.
>>
>> However, note that using standard dma funcs causes the following downsides:
>>
>> ...
>>
>> 3) OMAPFB_GET_VRAM_INFO ioctl cannot return real values anymore. I
>> changed the ioctl to return 64M for all the values, which, I hope, the
>> applications will interpret as "there's enough vram".
> 
> Do at least OMAPFB_QUERY_MEM/OMAPFB_SETUP_MEM still work?
> 
>> 4) "vram" kernel parameter to define how much ram to reserve for video use no
>> longer works. The user needs to enable CMA and use "cma" parameter.
> 
> That's a significant change, you should update Documentation/ .

I've added the following documentation change:

diff --git a/Documentation/arm/OMAP/DSS b/Documentation/arm/OMAP/DSS
index a564cee..4484e02 100644
--- a/Documentation/arm/OMAP/DSS
+++ b/Documentation/arm/OMAP/DSS
@@ -285,7 +285,10 @@ FB0 +-- GFX  ---- LCD ---- LCD
 Misc notes
 ----------
 
-OMAP FB allocates the framebuffer memory using the OMAP VRAM allocator.
+OMAP FB allocates the framebuffer memory using the standard dma allocator. You
+can enable Contiguous Memory Allocator (CONFIG_CMA) to improve the dma
+allocator, and if CMA is enabled, you use "cma=" kernel parameter to increase
+the global memory area for CMA.
 
 Using DSI DPLL to generate pixel clock it is possible produce the pixel clock
 of 86.5MHz (max possible), and with that you get 1280x1024@57 output from DVI.
@@ -301,11 +304,6 @@ framebuffer parameters.
 Kernel boot arguments
 ---------------------
 
-vram=<size>[,<physaddr>]
-       - Amount of total VRAM to preallocate and optionally a physical start
-         memory address. For example, "10M". omapfb allocates memory for
-         framebuffers from VRAM.
-




[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 897 bytes --]

^ permalink raw reply related

* Re: [PATCH 02/10] arm: at91: move platfarm_data to include/linux/platform_data/atmel.h
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-11-12 14:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAGhQ9VxgbCGzOPVtQq-LYsEPuyyGjRDfB3jHPtvbHr1xLgntXA@mail.gmail.com>

On 11:54 Sat 10 Nov     , Joachim Eastwood wrote:
> Hi Jean-Christophe,
> 
> On 7 November 2012 12:22, Jean-Christophe PLAGNIOL-VILLARD
> <plagnioj@jcrosoft.com> wrote:
> > Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> > Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
> > Cc: linux-ide@vger.kernel.org
> > Cc: linux-input@vger.kernel.org
> > Cc: linux-mmc@vger.kernel.org
> > Cc: linux-can@vger.kernel.org
> > Cc: netdev@vger.kernel.org
> > Cc: linux-pcmcia@lists.infradead.org
> > Cc: rtc-linux@googlegroups.com
> > Cc: spi-devel-general@lists.sourceforge.net
> > Cc: linux-serial@vger.kernel.org
> > Cc: linux-usb@vger.kernel.org
> > Cc: linux-fbdev@vger.kernel.org
> > ---
> > HI all,
> >
> >         If it's ok with everyone this will go via at91
> >         with the patch serie than clean up the include/mach
> >
> >         For preparation to switch to arm multiarch kernel
> >
> > Best Regards,
> > J.
> >  arch/arm/mach-at91/include/mach/board.h     |   55 ----------------------
> >  arch/avr32/mach-at32ap/include/mach/board.h |    7 ---
> >  drivers/ata/pata_at91.c                     |    2 +-
> >  drivers/input/touchscreen/atmel_tsadcc.c    |    2 +-
> >  drivers/mmc/host/atmel-mci.c                |    2 +-
> >  drivers/net/can/at91_can.c                  |    3 +-
> >  drivers/net/ethernet/cadence/at91_ether.c   |    2 +-
> >  drivers/pcmcia/at91_cf.c                    |    2 +-
> >  drivers/rtc/rtc-at91sam9.c                  |    2 +-
> >  drivers/spi/spi-atmel.c                     |    2 +-
> >  drivers/tty/serial/atmel_serial.c           |    2 +-
> >  drivers/usb/gadget/at91_udc.c               |    2 +-
> >  drivers/usb/gadget/atmel_usba_udc.c         |    2 +-
> >  drivers/usb/host/ohci-at91.c                |    2 +-
> >  drivers/video/atmel_lcdfb.c                 |    2 +-
> >  include/linux/platform_data/atmel.h         |   67 +++++++++++++++++++++++++++
> >  16 files changed, 80 insertions(+), 76 deletions(-)
> 
> <snip>
> 
> > diff --git a/drivers/net/ethernet/cadence/at91_ether.c b/drivers/net/ethernet/cadence/at91_ether.c
> > index 4e980a7..35fc6edb 100644
> > --- a/drivers/net/ethernet/cadence/at91_ether.c
> > +++ b/drivers/net/ethernet/cadence/at91_ether.c
> > @@ -31,6 +31,7 @@
> >  #include <linux/clk.h>
> >  #include <linux/gfp.h>
> >  #include <linux/phy.h>
> > +#include <linux/platform_data/atmel.h>
> >
> >  #include <asm/io.h>
> >  #include <asm/uaccess.h>
> > @@ -38,7 +39,6 @@
> >
> >  #include <mach/at91rm9200_emac.h>
> >  #include <asm/gpio.h>
> > -#include <mach/board.h>
> >
> >  #include "at91_ether.h"
> 
> The at91_ether driver in net-next does not need to be change since it
> all mach includes has already been removed by other patches and it
> includes linux/platform_data/macb.h directly.
> 
> What tree was these patches based on?
> The at91_ether driver changes has been in linux-next for a long while now.
the conflict is minor easy to handle and the cleanup need to go first on arm soc so this is
based on rc3

Best Regards,
J.

^ permalink raw reply

* Re: [PATCHv6 0/2] Add support for the OLED in the CFA10036
From: Maxime Ripard @ 2012-11-12 14:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351674774-2891-1-git-send-email-maxime.ripard@free-electrons.com>

Ping?

Le 31/10/2012 10:12, Maxime Ripard a écrit :
> Hi everyone,
> 
> This patchset adds support for the solomon SSD1307 OLED controller present
> in the CFA-10036 board.
> 
> It first adds the framebuffer driver for this controller, and then the
> needed bits to enable it in the cfa10036 dts.
> 
> Considering that the driver has been around since almost three months now, and
> I have not received any comments on the framebuffer part, I'd very much like it
> to be included in 3.8 if possible.
> 
> Thanks,
> Maxime
> 
> Changes from v5:
>   * Fixed bogus reset code
> 
> Maxime Ripard (2):
>   video: Add support for the Solomon SSD1307 OLED Controller
>   ARM: dts: mxs: add oled support for the cfa-10036
> 
>  .../devicetree/bindings/video/ssd1307fb.txt        |   24 ++
>  arch/arm/boot/dts/imx28-cfa10036.dts               |   19 +
>  drivers/video/Kconfig                              |   13 +
>  drivers/video/Makefile                             |    1 +
>  drivers/video/ssd1307fb.c                          |  407 ++++++++++++++++++++
>  5 files changed, 464 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/video/ssd1307fb.txt
>  create mode 100644 drivers/video/ssd1307fb.c
> 


-- 
Maxime Ripard, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

^ permalink raw reply

* [PATCH v8 0/6] of: add display helper
From: Steffen Trumtrar @ 2012-11-12 15:37 UTC (permalink / raw)
  To: devicetree-discuss
  Cc: Steffen Trumtrar, Rob Herring, linux-fbdev, dri-devel,
	Laurent Pinchart, Thierry Reding, Guennady Liakhovetski,
	linux-media, Tomi Valkeinen, Stephen Warren, kernel

Hi!

This is v8 of the display helper series

Changes since v7:
	- move of_xxx to drivers/video
	- remove non-binding documentation from display-timings.txt
	- squash display_timings and videomode in one patch
	- misc minor fixes

Regards,
Steffen


Steffen Trumtrar (6):
  video: add display_timing and videomode
  video: add of helper for videomode
  fbmon: add videomode helpers
  fbmon: add of_videomode helpers
  drm_modes: add videomode helpers
  drm_modes: add of_videomode helpers

 .../devicetree/bindings/video/display-timings.txt  |  107 +++++++++++
 drivers/gpu/drm/drm_modes.c                        |   77 ++++++++
 drivers/video/Kconfig                              |   19 ++
 drivers/video/Makefile                             |    4 +
 drivers/video/display_timing.c                     |   22 +++
 drivers/video/fbmon.c                              |   77 ++++++++
 drivers/video/of_display_timing.c                  |  186 ++++++++++++++++++++
 drivers/video/of_videomode.c                       |   47 +++++
 drivers/video/videomode.c                          |   45 +++++
 include/drm/drmP.h                                 |    8 +
 include/linux/display_timing.h                     |   69 ++++++++
 include/linux/fb.h                                 |    5 +
 include/linux/of_display_timings.h                 |   19 ++
 include/linux/of_videomode.h                       |   15 ++
 include/linux/videomode.h                          |   39 ++++
 15 files changed, 739 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/display-timings.txt
 create mode 100644 drivers/video/display_timing.c
 create mode 100644 drivers/video/of_display_timing.c
 create mode 100644 drivers/video/of_videomode.c
 create mode 100644 drivers/video/videomode.c
 create mode 100644 include/linux/display_timing.h
 create mode 100644 include/linux/of_display_timings.h
 create mode 100644 include/linux/of_videomode.h
 create mode 100644 include/linux/videomode.h

-- 
1.7.10.4


^ permalink raw reply

* [PATCH v8 1/6] video: add display_timing and videomode
From: Steffen Trumtrar @ 2012-11-12 15:37 UTC (permalink / raw)
  To: devicetree-discuss
  Cc: Steffen Trumtrar, Rob Herring, linux-fbdev, dri-devel,
	Laurent Pinchart, Thierry Reding, Guennady Liakhovetski,
	linux-media, Tomi Valkeinen, Stephen Warren, kernel
In-Reply-To: <1352734626-27412-1-git-send-email-s.trumtrar@pengutronix.de>

Add display_timing structure and the according helper functions. This allows
the description of a display via its supported timing parameters.

Every timing parameter can be specified as a single value or a range
<min typ max>.

Also, add helper functions to convert from display timings to a generic videomode
structure. This videomode can then be converted to the corresponding subsystem
mode representation (e.g. fb_videomode).

Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
 drivers/video/Kconfig          |    6 ++++
 drivers/video/Makefile         |    2 ++
 drivers/video/display_timing.c |   22 +++++++++++++
 drivers/video/videomode.c      |   45 ++++++++++++++++++++++++++
 include/linux/display_timing.h |   69 ++++++++++++++++++++++++++++++++++++++++
 include/linux/videomode.h      |   39 +++++++++++++++++++++++
 6 files changed, 183 insertions(+)
 create mode 100644 drivers/video/display_timing.c
 create mode 100644 drivers/video/videomode.c
 create mode 100644 include/linux/display_timing.h
 create mode 100644 include/linux/videomode.h

diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index d08d799..2a23b18 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -33,6 +33,12 @@ config VIDEO_OUTPUT_CONTROL
 	  This framework adds support for low-level control of the video 
 	  output switch.
 
+config DISPLAY_TIMING
+       bool
+
+config VIDEOMODE
+       bool
+
 menuconfig FB
 	tristate "Support for frame buffer devices"
 	---help---
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 23e948e..fc30439 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -167,3 +167,5 @@ obj-$(CONFIG_FB_VIRTUAL)          += vfb.o
 
 #video output switch sysfs driver
 obj-$(CONFIG_VIDEO_OUTPUT_CONTROL) += output.o
+obj-$(CONFIG_DISPLAY_TIMING) += display_timing.o
+obj-$(CONFIG_VIDEOMODE) += videomode.o
diff --git a/drivers/video/display_timing.c b/drivers/video/display_timing.c
new file mode 100644
index 0000000..04b7b69
--- /dev/null
+++ b/drivers/video/display_timing.c
@@ -0,0 +1,22 @@
+/*
+ * generic display timing functions
+ *
+ * Copyright (c) 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>, Pengutronix
+ *
+ * This file is released under the GPLv2
+ */
+
+#include <linux/display_timing.h>
+#include <linux/slab.h>
+
+void display_timings_release(struct display_timings *disp)
+{
+	if (disp->timings) {
+		unsigned int i;
+
+		for (i = 0; i < disp->num_timings; i++)
+			kfree(disp->timings[i]);
+		kfree(disp->timings);
+	}
+	kfree(disp);
+}
diff --git a/drivers/video/videomode.c b/drivers/video/videomode.c
new file mode 100644
index 0000000..087374a
--- /dev/null
+++ b/drivers/video/videomode.c
@@ -0,0 +1,45 @@
+/*
+ * generic display timing functions
+ *
+ * Copyright (c) 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>, Pengutronix
+ *
+ * This file is released under the GPLv2
+ */
+
+#include <linux/export.h>
+#include <linux/errno.h>
+#include <linux/display_timing.h>
+#include <linux/kernel.h>
+#include <linux/videomode.h>
+
+int videomode_from_timing(struct display_timings *disp, struct videomode *vm,
+			  unsigned int index)
+{
+	struct display_timing *dt;
+
+	dt = display_timings_get(disp, index);
+	if (!dt)
+		return -EINVAL;
+
+	vm->pixelclock = display_timing_get_value(&dt->pixelclock, 0);
+	vm->hactive = display_timing_get_value(&dt->hactive, 0);
+	vm->hfront_porch = display_timing_get_value(&dt->hfront_porch, 0);
+	vm->hback_porch = display_timing_get_value(&dt->hback_porch, 0);
+	vm->hsync_len = display_timing_get_value(&dt->hsync_len, 0);
+
+	vm->vactive = display_timing_get_value(&dt->vactive, 0);
+	vm->vfront_porch = display_timing_get_value(&dt->vfront_porch, 0);
+	vm->vback_porch = display_timing_get_value(&dt->vback_porch, 0);
+	vm->vsync_len = display_timing_get_value(&dt->vsync_len, 0);
+
+	vm->vah = dt->vsync_pol_active;
+	vm->hah = dt->hsync_pol_active;
+	vm->de = dt->de_pol_active;
+	vm->pixelclk_pol = dt->pixelclk_pol;
+
+	vm->interlaced = dt->interlaced;
+	vm->doublescan = dt->doublescan;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(videomode_from_timing);
diff --git a/include/linux/display_timing.h b/include/linux/display_timing.h
new file mode 100644
index 0000000..0ed2a1e
--- /dev/null
+++ b/include/linux/display_timing.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ *
+ * description of display timings
+ *
+ * This file is released under the GPLv2
+ */
+
+#ifndef __LINUX_DISPLAY_TIMINGS_H
+#define __LINUX_DISPLAY_TIMINGS_H
+
+#include <linux/types.h>
+
+struct timing_entry {
+	u32 min;
+	u32 typ;
+	u32 max;
+};
+
+struct display_timing {
+	struct timing_entry pixelclock;
+
+	struct timing_entry hactive;
+	struct timing_entry hfront_porch;
+	struct timing_entry hback_porch;
+	struct timing_entry hsync_len;
+
+	struct timing_entry vactive;
+	struct timing_entry vfront_porch;
+	struct timing_entry vback_porch;
+	struct timing_entry vsync_len;
+
+	unsigned int vsync_pol_active;
+	unsigned int hsync_pol_active;
+	unsigned int de_pol_active;
+	unsigned int pixelclk_pol;
+	bool interlaced;
+	bool doublescan;
+};
+
+struct display_timings {
+	unsigned int num_timings;
+	unsigned int native_mode;
+
+	struct display_timing **timings;
+};
+
+/* placeholder function until ranges are really needed 
+ * the index parameter should then be used to select one of [min typ max]
+ */
+static inline u32 display_timing_get_value(struct timing_entry *te,
+					   unsigned int index)
+{
+	return te->typ;
+}
+
+static inline struct display_timing *display_timings_get(struct display_timings *disp,
+							 unsigned int index)
+{
+	if (disp->num_timings > index)
+		return disp->timings[index];
+	else
+		return NULL;
+}
+
+void timings_release(struct display_timings *disp);
+void display_timings_release(struct display_timings *disp);
+
+#endif
diff --git a/include/linux/videomode.h b/include/linux/videomode.h
new file mode 100644
index 0000000..0b87fbb
--- /dev/null
+++ b/include/linux/videomode.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ *
+ * generic videomode description
+ *
+ * This file is released under the GPLv2
+ */
+
+#ifndef __LINUX_VIDEOMODE_H
+#define __LINUX_VIDEOMODE_H
+
+#include <linux/display_timing.h>
+
+struct videomode {
+	u32 pixelclock;
+	u32 refreshrate;
+
+	u32 hactive;
+	u32 hfront_porch;
+	u32 hback_porch;
+	u32 hsync_len;
+
+	u32 vactive;
+	u32 vfront_porch;
+	u32 vback_porch;
+	u32 vsync_len;
+
+	u32 hah;
+	u32 vah;
+	u32 de;
+	u32 pixelclk_pol;
+
+	bool interlaced;
+	bool doublescan;
+};
+
+int videomode_from_timing(struct display_timings *disp, struct videomode *vm,
+			  unsigned int index);
+#endif
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH v8 2/6] video: add of helper for videomode
From: Steffen Trumtrar @ 2012-11-12 15:37 UTC (permalink / raw)
  To: devicetree-discuss
  Cc: Steffen Trumtrar, Philipp Zabel, Rob Herring, linux-fbdev,
	dri-devel, Laurent Pinchart, Thierry Reding,
	Guennady Liakhovetski, linux-media, Tomi Valkeinen,
	Stephen Warren, kernel
In-Reply-To: <1352734626-27412-1-git-send-email-s.trumtrar@pengutronix.de>

This adds support for reading display timings from DT or/and convert one of those
timings to a videomode.
The of_display_timing implementation supports multiple children where each
property can have up to 3 values. All children are read into an array, that
can be queried.
of_get_videomode converts exactly one of that timings to a struct videomode.

Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
 .../devicetree/bindings/video/display-timings.txt  |  107 +++++++++++
 drivers/video/Kconfig                              |   13 ++
 drivers/video/Makefile                             |    2 +
 drivers/video/of_display_timing.c                  |  186 ++++++++++++++++++++
 drivers/video/of_videomode.c                       |   47 +++++
 include/linux/of_display_timings.h                 |   19 ++
 include/linux/of_videomode.h                       |   15 ++
 7 files changed, 389 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/display-timings.txt
 create mode 100644 drivers/video/of_display_timing.c
 create mode 100644 drivers/video/of_videomode.c
 create mode 100644 include/linux/of_display_timings.h
 create mode 100644 include/linux/of_videomode.h

diff --git a/Documentation/devicetree/bindings/video/display-timings.txt b/Documentation/devicetree/bindings/video/display-timings.txt
new file mode 100644
index 0000000..e22e2fd
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/display-timings.txt
@@ -0,0 +1,107 @@
+display-timings bindings
+============
+
+display-timings-node
+--------------------
+
+required properties:
+ - none
+
+optional properties:
+ - native-mode: the native mode for the display, in case multiple modes are
+		provided. When omitted, assume the first node is the native.
+
+timings-subnode
+---------------
+
+required properties:
+ - hactive, vactive: Display resolution
+ - hfront-porch, hback-porch, hsync-len: Horizontal Display timing parameters
+   in pixels
+   vfront-porch, vback-porch, vsync-len: Vertical display timing parameters in
+   lines
+ - clock-frequency: displayclock in Hz
+
+optional properties:
+ - hsync-active : Hsync pulse is active low/high/ignored
+ - vsync-active : Vsync pulse is active low/high/ignored
+ - de-active : Data-Enable pulse is active low/high/ignored
+ - pixelclk-inverted : pixelclock is inverted/non-inverted/ignored
+ - interlaced (bool)
+ - doublescan (bool)
+
+All the optional properties that are not bool follow the following logic:
+    <1> : high active
+    <0> : low active
+    omitted : not used on hardware
+
+There are different ways of describing the capabilities of a display. The devicetree
+representation corresponds to the one commonly found in datasheets for displays.
+If a display supports multiple signal timings, the native-mode can be specified.
+
+The parameters are defined as
+
+struct display_timing
+==========+
+  +----------+---------------------------------------------+----------+-------+
+  |          |                ↑                            |          |       |
+  |          |                |vback_porch                 |          |       |
+  |          |                ↓                            |          |       |
+  +----------###############################################----------+-------+
+  |          #                ↑                            #          |       |
+  |          #                |                            #          |       |
+  |  hback   #                |                            #  hfront  | hsync |
+  |   porch  #                |       hactive              #  porch   |  len  |
+  |<-------->#<---------------+--------------------------->#<-------->|<----->|
+  |          #                |                            #          |       |
+  |          #                |vactive                     #          |       |
+  |          #                |                            #          |       |
+  |          #                ↓                            #          |       |
+  +----------###############################################----------+-------+
+  |          |                ↑                            |          |       |
+  |          |                |vfront_porch                |          |       |
+  |          |                ↓                            |          |       |
+  +----------+---------------------------------------------+----------+-------+
+  |          |                ↑                            |          |       |
+  |          |                |vsync_len                   |          |       |
+  |          |                ↓                            |          |       |
+  +----------+---------------------------------------------+----------+-------+
+
+
+Example:
+
+	display-timings {
+		native-mode = <&timing0>;
+		timing0: 1920p24 {
+			/* 1920x1080p24 */
+			clock-frequency = <52000000>;
+			hactive = <1920>;
+			vactive = <1080>;
+			hfront-porch = <25>;
+			hback-porch = <25>;
+			hsync-len = <25>;
+			vback-porch = <2>;
+			vfront-porch = <2>;
+			vsync-len = <2>;
+			hsync-active = <1>;
+		};
+	};
+
+Every required property also supports the use of ranges, so the commonly used
+datasheet description with <min typ max>-tuples can be used.
+
+Example:
+
+	timing1: timing {
+		/* 1920x1080p24 */
+		clock-frequency = <148500000>;
+		hactive = <1920>;
+		vactive = <1080>;
+		hsync-len = <0 44 60>;
+		hfront-porch = <80 88 95>;
+		hback-porch = <100 148 160>;
+		vfront-porch = <0 4 6>;
+		vback-porch = <0 36 50>;
+		vsync-len = <0 5 6>;
+	};
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 2a23b18..a324457 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -39,6 +39,19 @@ config DISPLAY_TIMING
 config VIDEOMODE
        bool
 
+config OF_DISPLAY_TIMING
+	def_bool y
+	select DISPLAY_TIMING
+	help
+	  helper to parse display timings from the devicetree
+
+config OF_VIDEOMODE
+	def_bool y
+	select VIDEOMODE
+	select OF_DISPLAY_TIMING
+	help
+	  helper to get videomodes from the devicetree
+
 menuconfig FB
 	tristate "Support for frame buffer devices"
 	---help---
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index fc30439..b936b00 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -168,4 +168,6 @@ obj-$(CONFIG_FB_VIRTUAL)          += vfb.o
 #video output switch sysfs driver
 obj-$(CONFIG_VIDEO_OUTPUT_CONTROL) += output.o
 obj-$(CONFIG_DISPLAY_TIMING) += display_timing.o
+obj-$(CONFIG_OF_DISPLAY_TIMING) += of_display_timing.o
 obj-$(CONFIG_VIDEOMODE) += videomode.o
+obj-$(CONFIG_OF_VIDEOMODE) += of_videomode.o
diff --git a/drivers/video/of_display_timing.c b/drivers/video/of_display_timing.c
new file mode 100644
index 0000000..0bd30cc
--- /dev/null
+++ b/drivers/video/of_display_timing.c
@@ -0,0 +1,186 @@
+/*
+ * OF helpers for parsing display timings
+ *
+ * Copyright (c) 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>, Pengutronix
+ *
+ * based on of_videomode.c by Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * This file is released under the GPLv2
+ */
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/export.h>
+#include <linux/of_display_timings.h>
+
+/**
+ * parse_property - parse timing_entry from device_node
+ * @np: device_node with the property
+ * @name: name of the property
+ * @result: will be set to the return value
+ *
+ * DESCRIPTION:
+ * Every display_timing can be specified with either just the typical value or
+ * a range consisting of min/typ/max. This function helps handling this
+ **/
+static int parse_property(struct device_node *np, char *name,
+				struct timing_entry *result)
+{
+	struct property *prop;
+	int length, cells, ret;
+
+	prop = of_find_property(np, name, &length);
+	if (!prop) {
+		pr_err("%s: could not find property %s\n", __func__, name);
+		return -EINVAL;
+	}
+
+	cells = length / sizeof(u32);
+	if (cells = 1) {
+		ret = of_property_read_u32(np, name, &result->typ);
+		result->min = result->typ;
+		result->max = result->typ;
+	} else if (cells = 3) {
+		ret = of_property_read_u32_array(np, name, &result->min, cells);
+	} else {
+		pr_err("%s: illegal timing specification in %s\n", __func__, name);
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+/**
+ * of_get_display_timing - parse display_timing entry from device_node
+ * @np: device_node with the properties
+ **/
+static struct display_timing *of_get_display_timing(struct device_node *np)
+{
+	struct display_timing *dt;
+	int ret = 0;
+
+	dt = kzalloc(sizeof(*dt), GFP_KERNEL);
+	if (!dt) {
+		pr_err("%s: could not allocate display_timing struct\n", __func__);
+		return NULL;
+	}
+
+	ret |= parse_property(np, "hback-porch", &dt->hback_porch);
+	ret |= parse_property(np, "hfront-porch", &dt->hfront_porch);
+	ret |= parse_property(np, "hactive", &dt->hactive);
+	ret |= parse_property(np, "hsync-len", &dt->hsync_len);
+	ret |= parse_property(np, "vback-porch", &dt->vback_porch);
+	ret |= parse_property(np, "vfront-porch", &dt->vfront_porch);
+	ret |= parse_property(np, "vactive", &dt->vactive);
+	ret |= parse_property(np, "vsync-len", &dt->vsync_len);
+	ret |= parse_property(np, "clock-frequency", &dt->pixelclock);
+
+	of_property_read_u32(np, "vsync-active", &dt->vsync_pol_active);
+	of_property_read_u32(np, "hsync-active", &dt->hsync_pol_active);
+	of_property_read_u32(np, "de-active", &dt->de_pol_active);
+	of_property_read_u32(np, "pixelclk-inverted", &dt->pixelclk_pol);
+	dt->interlaced = of_property_read_bool(np, "interlaced");
+	dt->doublescan = of_property_read_bool(np, "doublescan");
+
+	if (ret) {
+		pr_err("%s: error reading timing properties\n", __func__);
+		return NULL;
+	}
+
+	return dt;
+}
+
+/**
+ * of_get_display_timings - parse all display_timing entries from a device_node
+ * @np: device_node with the subnodes
+ **/
+struct display_timings *of_get_display_timings(struct device_node *np)
+{
+	struct device_node *timings_np;
+	struct device_node *entry;
+	struct device_node *native_mode;
+	struct display_timings *disp;
+
+	if (!np) {
+		pr_err("%s: no devicenode given\n", __func__);
+		return NULL;
+	}
+
+	timings_np = of_find_node_by_name(np, "display-timings");
+	if (!timings_np) {
+		pr_err("%s: could not find display-timings node\n", __func__);
+		return NULL;
+	}
+
+	disp = kzalloc(sizeof(*disp), GFP_KERNEL);
+	if (!disp)
+		return -ENOMEM;
+
+	entry = of_parse_phandle(timings_np, "native-mode", 0);
+	/* assume first child as native mode if none provided */
+	if (!entry)
+		entry = of_get_next_child(np, NULL);
+	if (!entry) {
+		pr_err("%s: no timing specifications given\n", __func__);
+		return NULL;
+	}
+
+	pr_info("%s: using %s as default timing\n", __func__, entry->name);
+
+	native_mode = entry;
+
+	disp->num_timings = of_get_child_count(timings_np);
+	disp->timings = kzalloc(sizeof(struct display_timing *)*disp->num_timings,
+				GFP_KERNEL);
+	if (!disp->timings)
+		return -ENOMEM;
+
+	disp->num_timings = 0;
+	disp->native_mode = 0;
+
+	for_each_child_of_node(timings_np, entry) {
+		struct display_timing *dt;
+
+		dt = of_get_display_timing(entry);
+		if (!dt) {
+			/* to not encourage wrong devicetrees, fail in case of an error */
+			pr_err("%s: error in timing %d\n", __func__, disp->num_timings+1);
+			return NULL;
+		}
+
+		if (native_mode = entry)
+			disp->native_mode = disp->num_timings;
+
+		disp->timings[disp->num_timings] = dt;
+		disp->num_timings++;
+	}
+	of_node_put(timings_np);
+
+	if (disp->num_timings > 0)
+		pr_info("%s: got %d timings. Using timing #%d as default\n", __func__,
+			disp->num_timings , disp->native_mode + 1);
+	else {
+		pr_err("%s: no valid timings specified\n", __func__);
+		return NULL;
+	}
+	return disp;
+}
+EXPORT_SYMBOL_GPL(of_get_display_timings);
+
+/**
+ * of_display_timings_exists - check if a display-timings node is provided
+ * @np: device_node with the timing
+ **/
+int of_display_timings_exists(struct device_node *np)
+{
+	struct device_node *timings_np;
+
+	if (!np)
+		return -EINVAL;
+
+	timings_np = of_parse_phandle(np, "display-timings", 0);
+	if (!timings_np)
+		return -EINVAL;
+
+	return 1;
+}
+EXPORT_SYMBOL_GPL(of_display_timings_exists);
diff --git a/drivers/video/of_videomode.c b/drivers/video/of_videomode.c
new file mode 100644
index 0000000..7051701
--- /dev/null
+++ b/drivers/video/of_videomode.c
@@ -0,0 +1,47 @@
+/*
+ * generic videomode helper
+ *
+ * Copyright (c) 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>, Pengutronix
+ *
+ * This file is released under the GPLv2
+ */
+#include <linux/of.h>
+#include <linux/of_display_timings.h>
+#include <linux/of_videomode.h>
+#include <linux/export.h>
+
+/**
+ * of_get_videomode - get the videomode #<index> from devicetree
+ * @np - devicenode with the display_timings
+ * @vm - set to return value
+ * @index - index into list of display_timings
+ * DESCRIPTION:
+ * Get a list of all display timings and put the one
+ * specified by index into *vm. This function should only be used, if
+ * only one videomode is to be retrieved. A driver that needs to work
+ * with multiple/all videomodes should work with
+ * of_get_display_timings instead.
+ **/
+int of_get_videomode(struct device_node *np, struct videomode *vm, int index)
+{
+	struct display_timings *disp;
+	int ret;
+
+	disp = of_get_display_timings(np);
+	if (!disp) {
+		pr_err("%s: no timings specified\n", __func__);
+		return -EINVAL;
+	}
+
+	if (index = OF_USE_NATIVE_MODE)
+		index = disp->native_mode;
+
+	ret = videomode_from_timing(disp, vm, index);
+	if (ret)
+		return ret;
+
+	display_timings_release(disp);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(of_get_videomode);
diff --git a/include/linux/of_display_timings.h b/include/linux/of_display_timings.h
new file mode 100644
index 0000000..ccf6814
--- /dev/null
+++ b/include/linux/of_display_timings.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ *
+ * display timings of helpers
+ *
+ * This file is released under the GPLv2
+ */
+
+#ifndef __LINUX_OF_DISPLAY_TIMINGS_H
+#define __LINUX_OF_DISPLAY_TIMINGS_H
+
+#include <linux/display_timing.h>
+
+#define OF_USE_NATIVE_MODE -1
+
+struct display_timings *of_get_display_timings(struct device_node *np);
+int of_display_timings_exists(struct device_node *np);
+
+#endif
diff --git a/include/linux/of_videomode.h b/include/linux/of_videomode.h
new file mode 100644
index 0000000..01518e6
--- /dev/null
+++ b/include/linux/of_videomode.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ *
+ * videomode of-helpers
+ *
+ * This file is released under the GPLv2
+ */
+
+#ifndef __LINUX_OF_VIDEOMODE_H
+#define __LINUX_OF_VIDEOMODE_H
+
+#include <linux/videomode.h>
+
+int of_get_videomode(struct device_node *np, struct videomode *vm, int index);
+#endif /* __LINUX_OF_VIDEOMODE_H */
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH v8 3/6] fbmon: add videomode helpers
From: Steffen Trumtrar @ 2012-11-12 15:37 UTC (permalink / raw)
  To: devicetree-discuss
  Cc: Steffen Trumtrar, Rob Herring, linux-fbdev, dri-devel,
	Laurent Pinchart, Thierry Reding, Guennady Liakhovetski,
	linux-media, Tomi Valkeinen, Stephen Warren, kernel
In-Reply-To: <1352734626-27412-1-git-send-email-s.trumtrar@pengutronix.de>

Add a function to convert from the generic videomode to a fb_videomode.

Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
 drivers/video/fbmon.c |   37 +++++++++++++++++++++++++++++++++++++
 include/linux/fb.h    |    2 ++
 2 files changed, 39 insertions(+)

diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index cef6557..d46ecef 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -1373,6 +1373,43 @@ int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_inf
 	kfree(timings);
 	return err;
 }
+
+#if IS_ENABLED(CONFIG_VIDEOMODE)
+int videomode_to_fb_videomode(struct videomode *vm, struct fb_videomode *fbmode)
+{
+	fbmode->xres = vm->hactive;
+	fbmode->left_margin = vm->hback_porch;
+	fbmode->right_margin = vm->hfront_porch;
+	fbmode->hsync_len = vm->hsync_len;
+
+	fbmode->yres = vm->vactive;
+	fbmode->upper_margin = vm->vback_porch;
+	fbmode->lower_margin = vm->vfront_porch;
+	fbmode->vsync_len = vm->vsync_len;
+
+	fbmode->pixclock = KHZ2PICOS(vm->pixelclock / 1000);
+
+	fbmode->sync = 0;
+	fbmode->vmode = 0;
+	if (vm->hah)
+		fbmode->sync |= FB_SYNC_HOR_HIGH_ACT;
+	if (vm->vah)
+		fbmode->sync |= FB_SYNC_VERT_HIGH_ACT;
+	if (vm->interlaced)
+		fbmode->vmode |= FB_VMODE_INTERLACED;
+	if (vm->doublescan)
+		fbmode->vmode |= FB_VMODE_DOUBLE;
+	if (vm->de)
+		fbmode->sync |= FB_SYNC_DATA_ENABLE_HIGH_ACT;
+	fbmode->refresh = 60;
+	fbmode->flag = 0;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(videomode_to_fb_videomode);
+#endif
+
+
 #else
 int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var)
 {
diff --git a/include/linux/fb.h b/include/linux/fb.h
index c7a9571..46c665b 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -714,6 +714,8 @@ extern void fb_destroy_modedb(struct fb_videomode *modedb);
 extern int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb);
 extern unsigned char *fb_ddc_read(struct i2c_adapter *adapter);
 
+extern int videomode_to_fb_videomode(struct videomode *vm, struct fb_videomode *fbmode);
+
 /* drivers/video/modedb.c */
 #define VESA_MODEDB_SIZE 34
 extern void fb_var_to_videomode(struct fb_videomode *mode,
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH v8 4/6] fbmon: add of_videomode helpers
From: Steffen Trumtrar @ 2012-11-12 15:37 UTC (permalink / raw)
  To: devicetree-discuss
  Cc: Steffen Trumtrar, Rob Herring, linux-fbdev, dri-devel,
	Laurent Pinchart, Thierry Reding, Guennady Liakhovetski,
	linux-media, Tomi Valkeinen, Stephen Warren, kernel
In-Reply-To: <1352734626-27412-1-git-send-email-s.trumtrar@pengutronix.de>

Add helper to get fb_videomode from devicetree.

Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
 drivers/video/fbmon.c |   40 ++++++++++++++++++++++++++++++++++++++++
 include/linux/fb.h    |    3 +++
 2 files changed, 43 insertions(+)

diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index d46ecef..c95be79 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -1409,6 +1409,46 @@ int videomode_to_fb_videomode(struct videomode *vm, struct fb_videomode *fbmode)
 EXPORT_SYMBOL_GPL(videomode_to_fb_videomode);
 #endif
 
+#if IS_ENABLED(CONFIG_OF_VIDEOMODE)
+static void dump_fb_videomode(struct fb_videomode *m)
+{
+	pr_debug("fb_videomode = %ux%u@%uHz (%ukHz) %u %u %u %u %u %u %u %u %u\n",
+		 m->xres, m->yres, m->refresh, m->pixclock, m->left_margin,
+		 m->right_margin, m->upper_margin, m->lower_margin,
+		 m->hsync_len, m->vsync_len, m->sync, m->vmode, m->flag);
+}
+
+/**
+ * of_get_fb_videomode - get a fb_videomode from devicetree
+ * @np: device_node with the timing specification
+ * @fb: will be set to the return value
+ * @index: index into the list of display timings in devicetree
+ *
+ * DESCRIPTION:
+ * This function is expensive and should only be used, if only one mode is to be
+ * read from DT. To get multiple modes start with of_get_display_timings ond
+ * work with that instead.
+ */
+int of_get_fb_videomode(struct device_node *np, struct fb_videomode *fb,
+			int index)
+{
+	struct videomode vm;
+	int ret;
+
+	ret = of_get_videomode(np, &vm, index);
+	if (ret)
+		return ret;
+
+	videomode_to_fb_videomode(&vm, fb);
+
+	pr_info("%s: got %dx%d display mode from %s\n", __func__, vm.hactive,
+		vm.vactive, np->name);
+	dump_fb_videomode(fb);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(of_get_fb_videomode);
+#endif
 
 #else
 int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var)
diff --git a/include/linux/fb.h b/include/linux/fb.h
index 46c665b..9892fd6 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -14,6 +14,8 @@
 #include <linux/backlight.h>
 #include <linux/slab.h>
 #include <asm/io.h>
+#include <linux/of.h>
+#include <linux/of_videomode.h>
 
 struct vm_area_struct;
 struct fb_info;
@@ -714,6 +716,7 @@ extern void fb_destroy_modedb(struct fb_videomode *modedb);
 extern int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb);
 extern unsigned char *fb_ddc_read(struct i2c_adapter *adapter);
 
+extern int of_get_fb_videomode(struct device_node *np, struct fb_videomode *fb, int index);
 extern int videomode_to_fb_videomode(struct videomode *vm, struct fb_videomode *fbmode);
 
 /* drivers/video/modedb.c */
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH v8 5/6] drm_modes: add videomode helpers
From: Steffen Trumtrar @ 2012-11-12 15:37 UTC (permalink / raw)
  To: devicetree-discuss
  Cc: Steffen Trumtrar, Rob Herring, linux-fbdev, dri-devel,
	Laurent Pinchart, Thierry Reding, Guennady Liakhovetski,
	linux-media, Tomi Valkeinen, Stephen Warren, kernel
In-Reply-To: <1352734626-27412-1-git-send-email-s.trumtrar@pengutronix.de>

Add conversion from videomode to drm_display_mode

Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
 drivers/gpu/drm/drm_modes.c |   36 ++++++++++++++++++++++++++++++++++++
 include/drm/drmP.h          |    3 +++
 2 files changed, 39 insertions(+)

diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 59450f3..049624d 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -35,6 +35,7 @@
 #include <linux/export.h>
 #include <drm/drmP.h>
 #include <drm/drm_crtc.h>
+#include <linux/videomode.h>
 
 /**
  * drm_mode_debug_printmodeline - debug print a mode
@@ -504,6 +505,41 @@ drm_gtf_mode(struct drm_device *dev, int hdisplay, int vdisplay, int vrefresh,
 }
 EXPORT_SYMBOL(drm_gtf_mode);
 
+#if IS_ENABLED(CONFIG_VIDEOMODE)
+int videomode_to_display_mode(struct videomode *vm, struct drm_display_mode *dmode)
+{
+	dmode->hdisplay = vm->hactive;
+	dmode->hsync_start = dmode->hdisplay + vm->hfront_porch;
+	dmode->hsync_end = dmode->hsync_start + vm->hsync_len;
+	dmode->htotal = dmode->hsync_end + vm->hback_porch;
+
+	dmode->vdisplay = vm->vactive;
+	dmode->vsync_start = dmode->vdisplay + vm->vfront_porch;
+	dmode->vsync_end = dmode->vsync_start + vm->vsync_len;
+	dmode->vtotal = dmode->vsync_end + vm->vback_porch;
+
+	dmode->clock = vm->pixelclock / 1000;
+
+	dmode->flags = 0;
+	if (vm->hah)
+		dmode->flags |= DRM_MODE_FLAG_PHSYNC;
+	else
+		dmode->flags |= DRM_MODE_FLAG_NHSYNC;
+	if (vm->vah)
+		dmode->flags |= DRM_MODE_FLAG_PVSYNC;
+	else
+		dmode->flags |= DRM_MODE_FLAG_NVSYNC;
+	if (vm->interlaced)
+		dmode->flags |= DRM_MODE_FLAG_INTERLACE;
+	if (vm->doublescan)
+		dmode->flags |= DRM_MODE_FLAG_DBLSCAN;
+	drm_mode_set_name(dmode);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(videomode_to_display_mode);
+#endif
+
 /**
  * drm_mode_set_name - set the name on a mode
  * @mode: name will be set in this mode
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 3fd8280..e9fa1e3 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -56,6 +56,7 @@
 #include <linux/cdev.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
+#include <linux/videomode.h>
 #if defined(__alpha__) || defined(__powerpc__)
 #include <asm/pgtable.h>	/* For pte_wrprotect */
 #endif
@@ -1454,6 +1455,8 @@ extern struct drm_display_mode *
 drm_mode_create_from_cmdline_mode(struct drm_device *dev,
 				  struct drm_cmdline_mode *cmd);
 
+extern int videomode_to_display_mode(struct videomode *vm,
+				     struct drm_display_mode *dmode);
 /* Modesetting support */
 extern void drm_vblank_pre_modeset(struct drm_device *dev, int crtc);
 extern void drm_vblank_post_modeset(struct drm_device *dev, int crtc);
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH v8 6/6] drm_modes: add of_videomode helpers
From: Steffen Trumtrar @ 2012-11-12 15:37 UTC (permalink / raw)
  To: devicetree-discuss
  Cc: Steffen Trumtrar, Rob Herring, linux-fbdev, dri-devel,
	Laurent Pinchart, Thierry Reding, Guennady Liakhovetski,
	linux-media, Tomi Valkeinen, Stephen Warren, kernel
In-Reply-To: <1352734626-27412-1-git-send-email-s.trumtrar@pengutronix.de>

Add helper to get drm_display_mode from devicetree.

Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
 drivers/gpu/drm/drm_modes.c |   41 +++++++++++++++++++++++++++++++++++++++++
 include/drm/drmP.h          |    5 +++++
 2 files changed, 46 insertions(+)

diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 049624d..c77da59 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -35,6 +35,7 @@
 #include <linux/export.h>
 #include <drm/drmP.h>
 #include <drm/drm_crtc.h>
+#include <linux/of.h>
 #include <linux/videomode.h>
 
 /**
@@ -540,6 +541,46 @@ int videomode_to_display_mode(struct videomode *vm, struct drm_display_mode *dmo
 EXPORT_SYMBOL_GPL(videomode_to_display_mode);
 #endif
 
+#if IS_ENABLED(CONFIG_OF_VIDEOMODE)
+static void dump_drm_displaymode(struct drm_display_mode *m)
+{
+	pr_debug("drm_displaymode = %d %d %d %d %d %d %d %d %d\n",
+		 m->hdisplay, m->hsync_start, m->hsync_end, m->htotal,
+		 m->vdisplay, m->vsync_start, m->vsync_end, m->vtotal,
+		 m->clock);
+}
+
+/**
+ * of_get_drm_display_mode - get a drm_display_mode from devicetree
+ * @np: device_node with the timing specification
+ * @dmode: will be set to the return value
+ * @index: index into the list of display timings in devicetree
+ * 
+ * This function is expensive and should only be used, if only one mode is to be
+ * read from DT. To get multiple modes start with of_get_display_timings and
+ * work with that instead.
+ */
+int of_get_drm_display_mode(struct device_node *np, struct drm_display_mode *dmode,
+			int index)
+{
+	struct videomode vm;
+	int ret;
+
+	ret = of_get_videomode(np, &vm, index);
+	if (ret)
+		return ret;
+
+	videomode_to_display_mode(&vm, dmode);
+
+	pr_info("%s: got %dx%d display mode from %s\n", __func__, vm.hactive,
+		vm.vactive, np->name);
+	dump_drm_displaymode(dmode);
+
+	return 0;
+
+}
+EXPORT_SYMBOL_GPL(of_get_drm_display_mode);
+#endif
 /**
  * drm_mode_set_name - set the name on a mode
  * @mode: name will be set in this mode
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index e9fa1e3..4f9c44e 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -56,6 +56,7 @@
 #include <linux/cdev.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
+#include <linux/of.h>
 #include <linux/videomode.h>
 #if defined(__alpha__) || defined(__powerpc__)
 #include <asm/pgtable.h>	/* For pte_wrprotect */
@@ -1457,6 +1458,10 @@ drm_mode_create_from_cmdline_mode(struct drm_device *dev,
 
 extern int videomode_to_display_mode(struct videomode *vm,
 				     struct drm_display_mode *dmode);
+extern int of_get_drm_display_mode(struct device_node *np,
+				   struct drm_display_mode *dmode,
+				   int index);
+
 /* Modesetting support */
 extern void drm_vblank_pre_modeset(struct drm_device *dev, int crtc);
 extern void drm_vblank_post_modeset(struct drm_device *dev, int crtc);
-- 
1.7.10.4


^ permalink raw reply related

* Re: [PATCH 0/2] Adding devm_ functions and DT support to MIPI driver
From: Shaik Ameer Basha @ 2012-11-12 18:23 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1352547285-12302-1-git-send-email-shaik.ameer@samsung.com>

Hi Tomi,

On Mon, Nov 12, 2012 at 6:05 PM, Tomi Valkeinen <tomba@iki.fi> wrote:
> Hi,
>
> On 2012-11-10 13:34, Shaik Ameer Basha wrote:
>> In this patch series,
>>
>> First patch adds the devm_ functions to the driver code for automatic
>> code cleanup.
>>
>> Second patch adds the DT support for the exynos mipi-dsi driver.
>> for DT support, mipi device node should supply the following
>> information to the mipi-dsi driver.
>> 1] dsim_config information
>> 2] d-phy setting information
>> 3] lcd poweron, reset information
>> 4] fb_videomode information
>>
>> refer the documentation files for further details.
>>
>> Shaik Ameer Basha (2):
>>   exynos-mipi-dsi: using devm_ functions for automatic cleanup
>>   video: exynos-mipi-dsi: Adding DT support to exynos mipi driver
>
> MIPI is an organization. DSI is a protocol from MIPI. MIPI has many
> protocols. Thus it doesn't make sense to say "MIPI driver", "MIPI
> display", or use names like "samsung,exynos-mipi".
>
> It's either "MIPI DSI" if you want to be exact, or just "DSI", which I
> think is clear from the context.

Thanks for pointing this out, It's a fault from my side.
I will be specific/careful from next time on-wards...

>
> What is "dsim"?
>

As Sylwester mentioned, mipi-dsim stands for MIPI DSI Master.

>  Tomi
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v8 2/6] video: add of helper for videomode
From: Sascha Hauer @ 2012-11-12 18:58 UTC (permalink / raw)
  To: Steffen Trumtrar
  Cc: devicetree-discuss, Philipp Zabel, Rob Herring, linux-fbdev,
	dri-devel, Laurent Pinchart, Thierry Reding,
	Guennady Liakhovetski, linux-media, Tomi Valkeinen,
	Stephen Warren, kernel
In-Reply-To: <1352734626-27412-3-git-send-email-s.trumtrar@pengutronix.de>

Hi Steffen,

You lose memory in several places:

On Mon, Nov 12, 2012 at 04:37:02PM +0100, Steffen Trumtrar wrote:
> +static struct display_timing *of_get_display_timing(struct device_node *np)
> +{
> +	struct display_timing *dt;
> +	int ret = 0;
> +
> +	dt = kzalloc(sizeof(*dt), GFP_KERNEL);
> +	if (!dt) {
> +		pr_err("%s: could not allocate display_timing struct\n", __func__);
> +		return NULL;
> +	}
> +
> +	ret |= parse_property(np, "hback-porch", &dt->hback_porch);
> +	ret |= parse_property(np, "hfront-porch", &dt->hfront_porch);
> +	ret |= parse_property(np, "hactive", &dt->hactive);
> +	ret |= parse_property(np, "hsync-len", &dt->hsync_len);
> +	ret |= parse_property(np, "vback-porch", &dt->vback_porch);
> +	ret |= parse_property(np, "vfront-porch", &dt->vfront_porch);
> +	ret |= parse_property(np, "vactive", &dt->vactive);
> +	ret |= parse_property(np, "vsync-len", &dt->vsync_len);
> +	ret |= parse_property(np, "clock-frequency", &dt->pixelclock);
> +
> +	of_property_read_u32(np, "vsync-active", &dt->vsync_pol_active);
> +	of_property_read_u32(np, "hsync-active", &dt->hsync_pol_active);
> +	of_property_read_u32(np, "de-active", &dt->de_pol_active);
> +	of_property_read_u32(np, "pixelclk-inverted", &dt->pixelclk_pol);
> +	dt->interlaced = of_property_read_bool(np, "interlaced");
> +	dt->doublescan = of_property_read_bool(np, "doublescan");
> +
> +	if (ret) {
> +		pr_err("%s: error reading timing properties\n", __func__);
> +		return NULL;

Here

> +	}
> +
> +	return dt;
> +}
> +
> +/**
> + * of_get_display_timings - parse all display_timing entries from a device_node
> + * @np: device_node with the subnodes
> + **/
> +struct display_timings *of_get_display_timings(struct device_node *np)
> +{
> +	struct device_node *timings_np;
> +	struct device_node *entry;
> +	struct device_node *native_mode;
> +	struct display_timings *disp;
> +
> +	if (!np) {
> +		pr_err("%s: no devicenode given\n", __func__);
> +		return NULL;
> +	}
> +
> +	timings_np = of_find_node_by_name(np, "display-timings");
> +	if (!timings_np) {
> +		pr_err("%s: could not find display-timings node\n", __func__);
> +		return NULL;
> +	}
> +
> +	disp = kzalloc(sizeof(*disp), GFP_KERNEL);
> +	if (!disp)
> +		return -ENOMEM;
> +
> +	entry = of_parse_phandle(timings_np, "native-mode", 0);
> +	/* assume first child as native mode if none provided */
> +	if (!entry)
> +		entry = of_get_next_child(np, NULL);
> +	if (!entry) {
> +		pr_err("%s: no timing specifications given\n", __func__);
> +		return NULL;

Here

> +	}
> +
> +	pr_info("%s: using %s as default timing\n", __func__, entry->name);
> +
> +	native_mode = entry;
> +
> +	disp->num_timings = of_get_child_count(timings_np);
> +	disp->timings = kzalloc(sizeof(struct display_timing *)*disp->num_timings,
> +				GFP_KERNEL);
> +	if (!disp->timings)
> +		return -ENOMEM;

Here

> +
> +	disp->num_timings = 0;
> +	disp->native_mode = 0;
> +
> +	for_each_child_of_node(timings_np, entry) {
> +		struct display_timing *dt;
> +
> +		dt = of_get_display_timing(entry);
> +		if (!dt) {
> +			/* to not encourage wrong devicetrees, fail in case of an error */
> +			pr_err("%s: error in timing %d\n", __func__, disp->num_timings+1);
> +			return NULL;

Here

> +		}
> +
> +		if (native_mode = entry)
> +			disp->native_mode = disp->num_timings;
> +
> +		disp->timings[disp->num_timings] = dt;
> +		disp->num_timings++;
> +	}
> +	of_node_put(timings_np);
> +
> +	if (disp->num_timings > 0)
> +		pr_info("%s: got %d timings. Using timing #%d as default\n", __func__,
> +			disp->num_timings , disp->native_mode + 1);
> +	else {
> +		pr_err("%s: no valid timings specified\n", __func__);
> +		return NULL;

and here

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply

* Re: [PATCH v8 2/6] video: add of helper for videomode
From: Alexey Klimov @ 2012-11-12 19:00 UTC (permalink / raw)
  To: Steffen Trumtrar
  Cc: devicetree-discuss, Philipp Zabel, Rob Herring, linux-fbdev,
	dri-devel, Laurent Pinchart, Thierry Reding,
	Guennady Liakhovetski, linux-media, Tomi Valkeinen,
	Stephen Warren, kernel
In-Reply-To: <1352734626-27412-3-git-send-email-s.trumtrar@pengutronix.de>

Hello Steffen,

On Mon, Nov 12, 2012 at 7:37 PM, Steffen Trumtrar
<s.trumtrar@pengutronix.de> wrote:
> This adds support for reading display timings from DT or/and convert one of those
> timings to a videomode.
> The of_display_timing implementation supports multiple children where each
> property can have up to 3 values. All children are read into an array, that
> can be queried.
> of_get_videomode converts exactly one of that timings to a struct videomode.
>
> Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
> ---
>  .../devicetree/bindings/video/display-timings.txt  |  107 +++++++++++
>  drivers/video/Kconfig                              |   13 ++
>  drivers/video/Makefile                             |    2 +
>  drivers/video/of_display_timing.c                  |  186 ++++++++++++++++++++
>  drivers/video/of_videomode.c                       |   47 +++++
>  include/linux/of_display_timings.h                 |   19 ++
>  include/linux/of_videomode.h                       |   15 ++
>  7 files changed, 389 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/video/display-timings.txt
>  create mode 100644 drivers/video/of_display_timing.c
>  create mode 100644 drivers/video/of_videomode.c
>  create mode 100644 include/linux/of_display_timings.h
>  create mode 100644 include/linux/of_videomode.h
>
> diff --git a/Documentation/devicetree/bindings/video/display-timings.txt b/Documentation/devicetree/bindings/video/display-timings.txt
> new file mode 100644
> index 0000000..e22e2fd
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/video/display-timings.txt
> @@ -0,0 +1,107 @@
> +display-timings bindings
> +============
> +
> +display-timings-node
> +--------------------
> +
> +required properties:
> + - none
> +
> +optional properties:
> + - native-mode: the native mode for the display, in case multiple modes are
> +               provided. When omitted, assume the first node is the native.
> +
> +timings-subnode
> +---------------
> +
> +required properties:
> + - hactive, vactive: Display resolution
> + - hfront-porch, hback-porch, hsync-len: Horizontal Display timing parameters
> +   in pixels
> +   vfront-porch, vback-porch, vsync-len: Vertical display timing parameters in
> +   lines
> + - clock-frequency: displayclock in Hz
> +
> +optional properties:
> + - hsync-active : Hsync pulse is active low/high/ignored
> + - vsync-active : Vsync pulse is active low/high/ignored
> + - de-active : Data-Enable pulse is active low/high/ignored
> + - pixelclk-inverted : pixelclock is inverted/non-inverted/ignored
> + - interlaced (bool)
> + - doublescan (bool)
> +
> +All the optional properties that are not bool follow the following logic:
> +    <1> : high active
> +    <0> : low active
> +    omitted : not used on hardware
> +
> +There are different ways of describing the capabilities of a display. The devicetree
> +representation corresponds to the one commonly found in datasheets for displays.
> +If a display supports multiple signal timings, the native-mode can be specified.
> +
> +The parameters are defined as
> +
> +struct display_timing
> +==========> +
> +  +----------+---------------------------------------------+----------+-------+
> +  |          |                ↑                            |          |       |
> +  |          |                |vback_porch                 |          |       |
> +  |          |                ↓                            |          |       |
> +  +----------###############################################----------+-------+
> +  |          #                ↑                            #          |       |
> +  |          #                |                            #          |       |
> +  |  hback   #                |                            #  hfront  | hsync |
> +  |   porch  #                |       hactive              #  porch   |  len  |
> +  |<-------->#<---------------+--------------------------->#<-------->|<----->|
> +  |          #                |                            #          |       |
> +  |          #                |vactive                     #          |       |
> +  |          #                |                            #          |       |
> +  |          #                ↓                            #          |       |
> +  +----------###############################################----------+-------+
> +  |          |                ↑                            |          |       |
> +  |          |                |vfront_porch                |          |       |
> +  |          |                ↓                            |          |       |
> +  +----------+---------------------------------------------+----------+-------+
> +  |          |                ↑                            |          |       |
> +  |          |                |vsync_len                   |          |       |
> +  |          |                ↓                            |          |       |
> +  +----------+---------------------------------------------+----------+-------+
> +
> +
> +Example:
> +
> +       display-timings {
> +               native-mode = <&timing0>;
> +               timing0: 1920p24 {
> +                       /* 1920x1080p24 */
> +                       clock-frequency = <52000000>;
> +                       hactive = <1920>;
> +                       vactive = <1080>;
> +                       hfront-porch = <25>;
> +                       hback-porch = <25>;
> +                       hsync-len = <25>;
> +                       vback-porch = <2>;
> +                       vfront-porch = <2>;
> +                       vsync-len = <2>;
> +                       hsync-active = <1>;
> +               };
> +       };
> +
> +Every required property also supports the use of ranges, so the commonly used
> +datasheet description with <min typ max>-tuples can be used.
> +
> +Example:
> +
> +       timing1: timing {
> +               /* 1920x1080p24 */
> +               clock-frequency = <148500000>;
> +               hactive = <1920>;
> +               vactive = <1080>;
> +               hsync-len = <0 44 60>;
> +               hfront-porch = <80 88 95>;
> +               hback-porch = <100 148 160>;
> +               vfront-porch = <0 4 6>;
> +               vback-porch = <0 36 50>;
> +               vsync-len = <0 5 6>;
> +       };
> diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
> index 2a23b18..a324457 100644
> --- a/drivers/video/Kconfig
> +++ b/drivers/video/Kconfig
> @@ -39,6 +39,19 @@ config DISPLAY_TIMING
>  config VIDEOMODE
>         bool
>
> +config OF_DISPLAY_TIMING
> +       def_bool y
> +       select DISPLAY_TIMING
> +       help
> +         helper to parse display timings from the devicetree
> +
> +config OF_VIDEOMODE
> +       def_bool y
> +       select VIDEOMODE
> +       select OF_DISPLAY_TIMING
> +       help
> +         helper to get videomodes from the devicetree
> +
>  menuconfig FB
>         tristate "Support for frame buffer devices"
>         ---help---
> diff --git a/drivers/video/Makefile b/drivers/video/Makefile
> index fc30439..b936b00 100644
> --- a/drivers/video/Makefile
> +++ b/drivers/video/Makefile
> @@ -168,4 +168,6 @@ obj-$(CONFIG_FB_VIRTUAL)          += vfb.o
>  #video output switch sysfs driver
>  obj-$(CONFIG_VIDEO_OUTPUT_CONTROL) += output.o
>  obj-$(CONFIG_DISPLAY_TIMING) += display_timing.o
> +obj-$(CONFIG_OF_DISPLAY_TIMING) += of_display_timing.o
>  obj-$(CONFIG_VIDEOMODE) += videomode.o
> +obj-$(CONFIG_OF_VIDEOMODE) += of_videomode.o
> diff --git a/drivers/video/of_display_timing.c b/drivers/video/of_display_timing.c
> new file mode 100644
> index 0000000..0bd30cc
> --- /dev/null
> +++ b/drivers/video/of_display_timing.c
> @@ -0,0 +1,186 @@
> +/*
> + * OF helpers for parsing display timings
> + *
> + * Copyright (c) 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>, Pengutronix
> + *
> + * based on of_videomode.c by Sascha Hauer <s.hauer@pengutronix.de>
> + *
> + * This file is released under the GPLv2
> + */
> +#include <linux/of.h>
> +#include <linux/slab.h>
> +#include <linux/export.h>
> +#include <linux/of_display_timings.h>
> +
> +/**
> + * parse_property - parse timing_entry from device_node
> + * @np: device_node with the property
> + * @name: name of the property
> + * @result: will be set to the return value
> + *
> + * DESCRIPTION:
> + * Every display_timing can be specified with either just the typical value or
> + * a range consisting of min/typ/max. This function helps handling this
> + **/
> +static int parse_property(struct device_node *np, char *name,
> +                               struct timing_entry *result)
> +{
> +       struct property *prop;
> +       int length, cells, ret;
> +
> +       prop = of_find_property(np, name, &length);
> +       if (!prop) {
> +               pr_err("%s: could not find property %s\n", __func__, name);
> +               return -EINVAL;
> +       }
> +
> +       cells = length / sizeof(u32);
> +       if (cells = 1) {
> +               ret = of_property_read_u32(np, name, &result->typ);
> +               result->min = result->typ;
> +               result->max = result->typ;
> +       } else if (cells = 3) {
> +               ret = of_property_read_u32_array(np, name, &result->min, cells);
> +       } else {
> +               pr_err("%s: illegal timing specification in %s\n", __func__, name);
> +               return -EINVAL;
> +       }
> +
> +       return ret;
> +}
> +
> +/**
> + * of_get_display_timing - parse display_timing entry from device_node
> + * @np: device_node with the properties
> + **/
> +static struct display_timing *of_get_display_timing(struct device_node *np)
> +{
> +       struct display_timing *dt;
> +       int ret = 0;
> +
> +       dt = kzalloc(sizeof(*dt), GFP_KERNEL);
> +       if (!dt) {
> +               pr_err("%s: could not allocate display_timing struct\n", __func__);
> +               return NULL;
> +       }
> +
> +       ret |= parse_property(np, "hback-porch", &dt->hback_porch);
> +       ret |= parse_property(np, "hfront-porch", &dt->hfront_porch);
> +       ret |= parse_property(np, "hactive", &dt->hactive);
> +       ret |= parse_property(np, "hsync-len", &dt->hsync_len);
> +       ret |= parse_property(np, "vback-porch", &dt->vback_porch);
> +       ret |= parse_property(np, "vfront-porch", &dt->vfront_porch);
> +       ret |= parse_property(np, "vactive", &dt->vactive);
> +       ret |= parse_property(np, "vsync-len", &dt->vsync_len);
> +       ret |= parse_property(np, "clock-frequency", &dt->pixelclock);
> +
> +       of_property_read_u32(np, "vsync-active", &dt->vsync_pol_active);
> +       of_property_read_u32(np, "hsync-active", &dt->hsync_pol_active);
> +       of_property_read_u32(np, "de-active", &dt->de_pol_active);
> +       of_property_read_u32(np, "pixelclk-inverted", &dt->pixelclk_pol);
> +       dt->interlaced = of_property_read_bool(np, "interlaced");
> +       dt->doublescan = of_property_read_bool(np, "doublescan");
> +
> +       if (ret) {
> +               pr_err("%s: error reading timing properties\n", __func__);
> +               return NULL;
> +       }
> +
> +       return dt;
> +}
> +
> +/**
> + * of_get_display_timings - parse all display_timing entries from a device_node
> + * @np: device_node with the subnodes
> + **/
> +struct display_timings *of_get_display_timings(struct device_node *np)
> +{
> +       struct device_node *timings_np;
> +       struct device_node *entry;
> +       struct device_node *native_mode;
> +       struct display_timings *disp;
> +
> +       if (!np) {
> +               pr_err("%s: no devicenode given\n", __func__);
> +               return NULL;
> +       }
> +
> +       timings_np = of_find_node_by_name(np, "display-timings");
> +       if (!timings_np) {
> +               pr_err("%s: could not find display-timings node\n", __func__);
> +               return NULL;
> +       }
> +
> +       disp = kzalloc(sizeof(*disp), GFP_KERNEL);
> +       if (!disp)
> +               return -ENOMEM;
> +
> +       entry = of_parse_phandle(timings_np, "native-mode", 0);
> +       /* assume first child as native mode if none provided */
> +       if (!entry)
> +               entry = of_get_next_child(np, NULL);
> +       if (!entry) {
> +               pr_err("%s: no timing specifications given\n", __func__);
> +               return NULL;
> +       }
> +
> +       pr_info("%s: using %s as default timing\n", __func__, entry->name);
> +
> +       native_mode = entry;
> +
> +       disp->num_timings = of_get_child_count(timings_np);
> +       disp->timings = kzalloc(sizeof(struct display_timing *)*disp->num_timings,
> +                               GFP_KERNEL);
> +       if (!disp->timings)
> +               return -ENOMEM;

Could you please check return values here ^^^ and above "disp kzalloc(sizeof(*disp), GFP_KERNEL);" ?
May be it's better to return NULL instead of -ENOMEM and put error message?


-- 
Best regards, Klimov Alexey

^ permalink raw reply

* Re: [PATCH v8 2/6] video: add of helper for videomode
From: Stephen Warren @ 2012-11-12 20:40 UTC (permalink / raw)
  To: Steffen Trumtrar
  Cc: devicetree-discuss, Philipp Zabel, Rob Herring, linux-fbdev,
	dri-devel, Laurent Pinchart, Thierry Reding,
	Guennady Liakhovetski, linux-media, Tomi Valkeinen, kernel
In-Reply-To: <1352734626-27412-3-git-send-email-s.trumtrar@pengutronix.de>

On 11/12/2012 08:37 AM, Steffen Trumtrar wrote:
> This adds support for reading display timings from DT or/and convert one of those
> timings to a videomode.
> The of_display_timing implementation supports multiple children where each
> property can have up to 3 values. All children are read into an array, that
> can be queried.
> of_get_videomode converts exactly one of that timings to a struct videomode.

> diff --git a/Documentation/devicetree/bindings/video/display-timings.txt b/Documentation/devicetree/bindings/video/display-timings.txt

The device tree bindings look reasonable to me, so,

Acked-by: Stephen Warren <swarren@nvidia.com>

^ permalink raw reply

* Re: [PATCH 0/5] OMAPFB: use dma_alloc instead of omap's vram
From: Tony Lindgren @ 2012-11-12 22:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1352715906-16946-1-git-send-email-tomi.valkeinen@ti.com>

* Tomi Valkeinen <tomi.valkeinen@ti.com> [121112 02:27]:
> Hi,
> 
> This series changes omapfb to use standard dma_alloc funcs instead of omap
> specific vram allocator. This let's us remove the omap vram allocator, making
> omapfb platform independent.
> 
> However, note that using standard dma funcs causes the following downsides:
> 
> 1) dma_alloc_attrs doesn't let us allocate at certain physical address.
> However, this should not be a problem as this feature of vram allocator
> is only used when reserving the framebuffer that was initialized by the
> bootloader, and we don't currently support "passing" a framebuffer from
> the bootloader to the kernel anyway.
> 
> 2) dma_alloc_attrs, as of now, always ioremaps the allocated area, and
> we don't need the ioremap when using VRFB. This patch uses
> DMA_ATTR_NO_KERNEL_MAPPING for the allocation, but the flag is currently
> not operational.
> 
> 3) OMAPFB_GET_VRAM_INFO ioctl cannot return real values anymore. I
> changed the ioctl to return 64M for all the values, which, I hope, the
> applications will interpret as "there's enough vram".
> 
> 4) "vram" kernel parameter to define how much ram to reserve for video use no
> longer works. The user needs to enable CMA and use "cma" parameter.

Great, thanks for fixing these. Could you please queue these into
a separate branch against v3.7-rc5 that I can also merge into
omap-for-v3.8/cleanup-headers-prepare-multiplatform-v3?

Feel free to add my Acked-by: Tony Lindgren <tony@atomide.com> to the
arch/arm/*omap*/* parts.

Regards,

Tony

^ permalink raw reply

* Re: [PATCH v8 2/6] video: add of helper for videomode
From: Steffen Trumtrar @ 2012-11-13  8:32 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: devicetree-discuss, Philipp Zabel, Rob Herring, linux-fbdev,
	dri-devel, Laurent Pinchart, Thierry Reding,
	Guennady Liakhovetski, linux-media, Tomi Valkeinen,
	Stephen Warren, kernel
In-Reply-To: <20121112185840.GX10369@pengutronix.de>

Hi!

On Mon, Nov 12, 2012 at 07:58:40PM +0100, Sascha Hauer wrote:
> Hi Steffen,
> 
> You lose memory in several places:
> 
> On Mon, Nov 12, 2012 at 04:37:02PM +0100, Steffen Trumtrar wrote:
> > +static struct display_timing *of_get_display_timing(struct device_node *np)
> > +{
> > +	struct display_timing *dt;
> > +	int ret = 0;
> > +
> > +	dt = kzalloc(sizeof(*dt), GFP_KERNEL);
> > +	if (!dt) {
> > +		pr_err("%s: could not allocate display_timing struct\n", __func__);
> > +		return NULL;
> > +	}
> > +
> > +	ret |= parse_property(np, "hback-porch", &dt->hback_porch);
> > +	ret |= parse_property(np, "hfront-porch", &dt->hfront_porch);
> > +	ret |= parse_property(np, "hactive", &dt->hactive);
> > +	ret |= parse_property(np, "hsync-len", &dt->hsync_len);
> > +	ret |= parse_property(np, "vback-porch", &dt->vback_porch);
> > +	ret |= parse_property(np, "vfront-porch", &dt->vfront_porch);
> > +	ret |= parse_property(np, "vactive", &dt->vactive);
> > +	ret |= parse_property(np, "vsync-len", &dt->vsync_len);
> > +	ret |= parse_property(np, "clock-frequency", &dt->pixelclock);
> > +
> > +	of_property_read_u32(np, "vsync-active", &dt->vsync_pol_active);
> > +	of_property_read_u32(np, "hsync-active", &dt->hsync_pol_active);
> > +	of_property_read_u32(np, "de-active", &dt->de_pol_active);
> > +	of_property_read_u32(np, "pixelclk-inverted", &dt->pixelclk_pol);
> > +	dt->interlaced = of_property_read_bool(np, "interlaced");
> > +	dt->doublescan = of_property_read_bool(np, "doublescan");
> > +
> > +	if (ret) {
> > +		pr_err("%s: error reading timing properties\n", __func__);
> > +		return NULL;
> 
> Here
> 
> > +	}
> > +
> > +	return dt;
> > +}
> > +
> > +/**
> > + * of_get_display_timings - parse all display_timing entries from a device_node
> > + * @np: device_node with the subnodes
> > + **/
> > +struct display_timings *of_get_display_timings(struct device_node *np)
> > +{
> > +	struct device_node *timings_np;
> > +	struct device_node *entry;
> > +	struct device_node *native_mode;
> > +	struct display_timings *disp;
> > +
> > +	if (!np) {
> > +		pr_err("%s: no devicenode given\n", __func__);
> > +		return NULL;
> > +	}
> > +
> > +	timings_np = of_find_node_by_name(np, "display-timings");
> > +	if (!timings_np) {
> > +		pr_err("%s: could not find display-timings node\n", __func__);
> > +		return NULL;
> > +	}
> > +
> > +	disp = kzalloc(sizeof(*disp), GFP_KERNEL);
> > +	if (!disp)
> > +		return -ENOMEM;
> > +
> > +	entry = of_parse_phandle(timings_np, "native-mode", 0);
> > +	/* assume first child as native mode if none provided */
> > +	if (!entry)
> > +		entry = of_get_next_child(np, NULL);
> > +	if (!entry) {
> > +		pr_err("%s: no timing specifications given\n", __func__);
> > +		return NULL;
> 
> Here
> 
> > +	}
> > +
> > +	pr_info("%s: using %s as default timing\n", __func__, entry->name);
> > +
> > +	native_mode = entry;
> > +
> > +	disp->num_timings = of_get_child_count(timings_np);
> > +	disp->timings = kzalloc(sizeof(struct display_timing *)*disp->num_timings,
> > +				GFP_KERNEL);
> > +	if (!disp->timings)
> > +		return -ENOMEM;
> 
> Here
> 
> > +
> > +	disp->num_timings = 0;
> > +	disp->native_mode = 0;
> > +
> > +	for_each_child_of_node(timings_np, entry) {
> > +		struct display_timing *dt;
> > +
> > +		dt = of_get_display_timing(entry);
> > +		if (!dt) {
> > +			/* to not encourage wrong devicetrees, fail in case of an error */
> > +			pr_err("%s: error in timing %d\n", __func__, disp->num_timings+1);
> > +			return NULL;
> 
> Here
> 
> > +		}
> > +
> > +		if (native_mode = entry)
> > +			disp->native_mode = disp->num_timings;
> > +
> > +		disp->timings[disp->num_timings] = dt;
> > +		disp->num_timings++;
> > +	}
> > +	of_node_put(timings_np);
> > +
> > +	if (disp->num_timings > 0)
> > +		pr_info("%s: got %d timings. Using timing #%d as default\n", __func__,
> > +			disp->num_timings , disp->native_mode + 1);
> > +	else {
> > +		pr_err("%s: no valid timings specified\n", __func__);
> > +		return NULL;
> 
> and here
> 

Well,... you are right. :-(

Regards,
Steffen

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox