Linux Framebuffer Layer development
 help / color / mirror / Atom feed
* [PATCH v3] video: Add Aeroflex Gaisler GRVGA framebuffer device driver
From: Kristoffer Glembo @ 2011-07-05  7:29 UTC (permalink / raw)
  To: linux-fbdev

This patch adds support for the GRVGA framebuffer IP core from Aeroflex Gaisler.
The device is used in LEON SPARCV8 based System on Chips. Documentation can
be found here: www.gaisler.com/products/grlib/grip.pdf.

Signed-off-by: Kristoffer Glembo <kristoffer@gaisler.com>
---
 drivers/video/Kconfig  |   10 +
 drivers/video/Makefile |    1 +
 drivers/video/grvga.c  |  579 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 590 insertions(+), 0 deletions(-)
 create mode 100644 drivers/video/grvga.c

diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 549b960..18ee201 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -259,6 +259,16 @@ config FB_TILEBLITTING
 comment "Frame buffer hardware drivers"
 	depends on FB
 
+config FB_GRVGA
+	tristate "Aeroflex Gaisler framebuffer support"
+	depends on FB && SPARC
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+	This enables support for the SVGACTRL framebuffer in the GRLIB IP library from Aeroflex Gaisler.
+
+
 config FB_CIRRUS
 	tristate "Cirrus Logic support"
 	depends on FB && (ZORRO || PCI)
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 8b83129..4cff5ec 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_FB_DEFERRED_IO)   += fb_defio.o
 obj-$(CONFIG_FB_WMT_GE_ROPS)   += wmt_ge_rops.o
 
 # Hardware specific drivers go first
+obj-$(CONFIG_FB_GRVGA)            += grvga.o
 obj-$(CONFIG_FB_AMIGA)            += amifb.o c2p_planar.o
 obj-$(CONFIG_FB_ARC)              += arcfb.o
 obj-$(CONFIG_FB_CLPS711X)         += clps711xfb.o
diff --git a/drivers/video/grvga.c b/drivers/video/grvga.c
new file mode 100644
index 0000000..f37e025
--- /dev/null
+++ b/drivers/video/grvga.c
@@ -0,0 +1,579 @@
+/*
+ * Driver for Aeroflex Gaisler SVGACTRL framebuffer device.
+ *
+ * 2011 (c) Aeroflex Gaisler AB
+ *
+ * Full documentation of the core can be found here:
+ * http://www.gaisler.com/products/grlib/grip.pdf
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Contributors: Kristoffer Glembo <kristoffer@gaisler.com>
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/of_platform.h>
+#include <linux/of_device.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
+#include <linux/io.h>
+
+struct grvga_regs {
+	u32 status; 		/* 0x00 */
+	u32 video_length; 	/* 0x04 */
+	u32 front_porch;	/* 0x08 */
+	u32 sync_length;	/* 0x0C */
+	u32 line_length;	/* 0x10 */
+	u32 fb_pos;		/* 0x14 */
+	u32 clk_vector[4];	/* 0x18 */
+	u32 clut;	        /* 0x20 */
+};
+
+struct grvga_par {
+	struct grvga_regs *regs;
+	u32 color_palette[16];  /* 16 entry pseudo palette used by fbcon in true color mode */
+	int clk_sel;
+	int fb_alloced;         /* = 1 if framebuffer is allocated in main memory */
+};
+
+
+static const struct fb_videomode grvga_modedb[] = {
+    {
+	/* 640x480 @ 60 Hz */
+	NULL, 60, 640, 480, 40000, 48, 16, 39, 11, 96, 2,
+	0, FB_VMODE_NONINTERLACED
+    }, {
+	/* 800x600 @ 60 Hz */
+	NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
+	0, FB_VMODE_NONINTERLACED
+    }, {
+	/* 800x600 @ 72 Hz */
+	NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
+	0, FB_VMODE_NONINTERLACED
+    }, {
+	/* 1024x768 @ 60 Hz */
+	NULL, 60, 1024, 768, 15385, 160, 24, 29, 3, 136, 6,
+	0, FB_VMODE_NONINTERLACED
+    }
+ };
+
+static struct fb_fix_screeninfo grvga_fix __initdata = {
+	.id =		"AG SVGACTRL",
+	.type =		FB_TYPE_PACKED_PIXELS,
+	.visual =       FB_VISUAL_PSEUDOCOLOR,
+	.xpanstep =	0,
+	.ypanstep =	1,
+	.ywrapstep =	0,
+	.accel =	FB_ACCEL_NONE,
+};
+
+static int grvga_check_var(struct fb_var_screeninfo *var,
+			   struct fb_info *info)
+{
+	struct grvga_par *par = info->par;
+	int i;
+
+	if (!var->xres)
+		var->xres = 1;
+	if (!var->yres)
+		var->yres = 1;
+	if (var->bits_per_pixel <= 8)
+		var->bits_per_pixel = 8;
+	else if (var->bits_per_pixel <= 16)
+		var->bits_per_pixel = 16;
+	else if (var->bits_per_pixel <= 24)
+		var->bits_per_pixel = 24;
+	else if (var->bits_per_pixel <= 32)
+		var->bits_per_pixel = 32;
+	else
+		return -EINVAL;
+
+	var->xres_virtual = var->xres;
+	var->yres_virtual = 2*var->yres;
+
+	if (info->fix.smem_len) {
+		if ((var->yres_virtual*var->xres_virtual*var->bits_per_pixel/8) > info->fix.smem_len)
+			return -ENOMEM;
+	}
+
+	/* Which clocks that are available can be read out in these registers */
+	for (i = 0; i <= 3 ; i++) {
+		if (var->pixclock = par->regs->clk_vector[i])
+			break;
+	}
+	if (i <= 3)
+		par->clk_sel = i;
+	else
+		return -EINVAL;
+
+	switch (info->var.bits_per_pixel) {
+	case 8:
+		var->red   = (struct fb_bitfield) {0, 8, 0};      /* offset, length, msb-right */
+		var->green = (struct fb_bitfield) {0, 8, 0};
+		var->blue  = (struct fb_bitfield) {0, 8, 0};
+		var->transp = (struct fb_bitfield) {0, 0, 0};
+		break;
+	case 16:
+		var->red   = (struct fb_bitfield) {11, 5, 0};
+		var->green = (struct fb_bitfield) {5, 6, 0};
+		var->blue  = (struct fb_bitfield) {0, 5, 0};
+		var->transp = (struct fb_bitfield) {0, 0, 0};
+		break;
+	case 24:
+	case 32:
+		var->red   = (struct fb_bitfield) {16, 8, 0};
+		var->green = (struct fb_bitfield) {8, 8, 0};
+		var->blue  = (struct fb_bitfield) {0, 8, 0};
+		var->transp = (struct fb_bitfield) {24, 8, 0};
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int grvga_set_par(struct fb_info *info)
+{
+
+	u32 func = 0;
+	struct grvga_par *par = info->par;
+
+	__raw_writel(((info->var.yres - 1) << 16) | (info->var.xres - 1),
+		     &par->regs->video_length);
+
+	__raw_writel((info->var.lower_margin << 16) | (info->var.right_margin),
+		     &par->regs->front_porch);
+
+	__raw_writel((info->var.vsync_len << 16) | (info->var.hsync_len),
+		     &par->regs->sync_length);
+
+	__raw_writel(((info->var.yres + info->var.lower_margin + info->var.upper_margin + info->var.vsync_len - 1) << 16) |
+		     (info->var.xres + info->var.right_margin + info->var.left_margin + info->var.hsync_len - 1),
+		     &par->regs->line_length);
+
+	switch (info->var.bits_per_pixel) {
+	case 8:
+		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+		func = 1;
+		break;
+	case 16:
+		info->fix.visual = FB_VISUAL_TRUECOLOR;
+		func = 2;
+		break;
+	case 24:
+	case 32:
+		info->fix.visual = FB_VISUAL_TRUECOLOR;
+		func = 3;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	__raw_writel((par->clk_sel << 6) | (func << 4) | 1,
+		     &par->regs->status);
+
+	info->fix.line_length = (info->var.xres_virtual*info->var.bits_per_pixel)/8;
+	return 0;
+}
+
+static int grvga_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info)
+{
+	struct grvga_par *par;
+	par = info->par;
+
+	if (regno >= 256)	/* Size of CLUT */
+		return -EINVAL;
+
+	if (info->var.grayscale) {
+		/* grayscale = 0.30*R + 0.59*G + 0.11*B */
+		red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
+	}
+
+
+
+#define CNVT_TOHW(val, width) ((((val)<<(width))+0x7FFF-(val))>>16)
+
+	red    = CNVT_TOHW(red,   info->var.red.length);
+	green  = CNVT_TOHW(green, info->var.green.length);
+	blue   = CNVT_TOHW(blue,  info->var.blue.length);
+	transp = CNVT_TOHW(transp, info->var.transp.length);
+
+#undef CNVT_TOHW
+
+	/* In PSEUDOCOLOR we use the hardware CLUT */
+	if (info->fix.visual = FB_VISUAL_PSEUDOCOLOR)
+		__raw_writel((regno << 24) | (red << 16) | (green << 8) | blue,
+			     &par->regs->clut);
+
+	/* Truecolor uses the pseudo palette */
+	else if (info->fix.visual = FB_VISUAL_TRUECOLOR) {
+		u32 v;
+		if (regno >= 16)
+			return -EINVAL;
+
+
+		v =     (red    << info->var.red.offset)   |
+			(green  << info->var.green.offset) |
+			(blue   << info->var.blue.offset)  |
+			(transp << info->var.transp.offset);
+
+		((u32 *) (info->pseudo_palette))[regno] = v;
+	}
+	return 0;
+}
+
+static int grvga_pan_display(struct fb_var_screeninfo *var,
+			     struct fb_info *info)
+{
+	struct grvga_par *par = info->par;
+	struct fb_fix_screeninfo *fix = &info->fix;
+	u32 base_addr;
+
+	if (var->xoffset != 0)
+		return -EINVAL;
+
+	base_addr = fix->smem_start + (var->yoffset * fix->line_length);
+	base_addr &= ~3UL;
+
+	/* Set framebuffer base address  */
+	__raw_writel(base_addr,
+		     &par->regs->fb_pos);
+
+	return 0;
+}
+
+static struct fb_ops grvga_ops = {
+	.owner          = THIS_MODULE,
+	.fb_check_var   = grvga_check_var,
+	.fb_set_par	= grvga_set_par,
+	.fb_setcolreg   = grvga_setcolreg,
+	.fb_pan_display = grvga_pan_display,
+	.fb_fillrect	= cfb_fillrect,
+	.fb_copyarea	= cfb_copyarea,
+	.fb_imageblit	= cfb_imageblit
+};
+
+static int __init grvga_parse_custom(char *options,
+				     struct fb_var_screeninfo *screendata)
+{
+	char *this_opt;
+	int count = 0;
+	if (!options || !*options)
+		return -1;
+
+	while ((this_opt = strsep(&options, " ")) != NULL) {
+		if (!*this_opt)
+			continue;
+
+		switch (count) {
+		case 0:
+			screendata->pixclock = simple_strtoul(this_opt, NULL, 0);
+			count++;
+			break;
+		case 1:
+			screendata->xres = screendata->xres_virtual = simple_strtoul(this_opt, NULL, 0);
+			count++;
+			break;
+		case 2:
+			screendata->right_margin = simple_strtoul(this_opt, NULL, 0);
+			count++;
+			break;
+		case 3:
+			screendata->hsync_len = simple_strtoul(this_opt, NULL, 0);
+			count++;
+			break;
+		case 4:
+			screendata->left_margin = simple_strtoul(this_opt, NULL, 0);
+			count++;
+			break;
+		case 5:
+			screendata->yres = screendata->yres_virtual = simple_strtoul(this_opt, NULL, 0);
+			count++;
+			break;
+		case 6:
+			screendata->lower_margin = simple_strtoul(this_opt, NULL, 0);
+			count++;
+			break;
+		case 7:
+			screendata->vsync_len = simple_strtoul(this_opt, NULL, 0);
+			count++;
+			break;
+		case 8:
+			screendata->upper_margin = simple_strtoul(this_opt, NULL, 0);
+			count++;
+			break;
+		case 9:
+			screendata->bits_per_pixel = simple_strtoul(this_opt, NULL, 0);
+			count++;
+			break;
+		default:
+			return -1;
+		}
+	}
+	screendata->activate  = FB_ACTIVATE_NOW;
+	screendata->vmode     = FB_VMODE_NONINTERLACED;
+	return 0;
+}
+
+static int __devinit grvga_probe(struct platform_device *dev)
+{
+	struct fb_info *info;
+	int retval = -ENOMEM;
+	unsigned long virtual_start;
+	unsigned long grvga_fix_addr = 0;
+	unsigned long physical_start = 0;
+	unsigned long grvga_mem_size = 0;
+	struct grvga_par *par = NULL;
+	char *options = NULL, *mode_opt = NULL;
+
+	info = framebuffer_alloc(sizeof(struct grvga_par), &dev->dev);
+	if (!info) {
+		dev_err(&dev->dev, "framebuffer_alloc failed\n");
+		return -ENOMEM;
+	}
+
+	/* Expecting: "grvga: modestring, [addr:<framebuffer physical address>], [size:<framebuffer size>]
+	 *
+	 * If modestring is custom:<custom mode string> we parse the string which then contains all videoparameters
+	 * If address is left out, we allocate memory,
+	 * if size is left out we only allocate enough to support the given mode.
+	 */
+	if (fb_get_options("grvga", &options)) {
+		retval = -ENODEV;
+		goto err;
+	}
+
+	if (!options || !*options)
+		options =  "640x480-8@60";
+
+	while (1) {
+		char *this_opt = strsep(&options, ",");
+
+		if (!this_opt)
+			break;
+
+		if (!strncmp(this_opt, "custom", 6)) {
+			if (grvga_parse_custom(this_opt, &info->var) < 0) {
+				dev_err(&dev->dev, "Failed to parse custom mode (%s).\n", this_opt);
+				retval = -EINVAL;
+				goto err1;
+			}
+		} else if (!strncmp(this_opt, "addr", 4))
+			grvga_fix_addr = simple_strtoul(this_opt + 5, NULL, 16);
+		else if (!strncmp(this_opt, "size", 4))
+			grvga_mem_size = simple_strtoul(this_opt + 5, NULL, 0);
+		else
+			mode_opt = this_opt;
+	}
+
+	par = info->par;
+	info->fbops = &grvga_ops;
+	info->fix = grvga_fix;
+	info->pseudo_palette = par->color_palette;
+	info->flags = FBINFO_DEFAULT | FBINFO_PARTIAL_PAN_OK | FBINFO_HWACCEL_YPAN;
+	info->fix.smem_len = grvga_mem_size;
+
+	if (!request_mem_region(dev->resource[0].start, resource_size(&dev->resource[0]), "grlib-svgactrl regs")) {
+		dev_err(&dev->dev, "registers already mapped\n");
+		retval = -EBUSY;
+		goto err;
+	}
+
+	par->regs = of_ioremap(&dev->resource[0], 0,
+			       resource_size(&dev->resource[0]),
+			       "grlib-svgactrl regs");
+
+	if (!par->regs) {
+		dev_err(&dev->dev, "failed to map registers\n");
+		retval = -ENOMEM;
+		goto err1;
+	}
+
+	retval = fb_alloc_cmap(&info->cmap, 256, 0);
+	if (retval < 0) {
+		dev_err(&dev->dev, "failed to allocate mem with fb_alloc_cmap\n");
+		retval = -ENOMEM;
+		goto err2;
+	}
+
+	if (mode_opt) {
+		retval = fb_find_mode(&info->var, info, mode_opt,
+				      grvga_modedb, sizeof(grvga_modedb), &grvga_modedb[0], 8);
+		if (!retval || retval = 4) {
+			retval = -EINVAL;
+			goto err3;
+		}
+	}
+
+	if (!grvga_mem_size)
+		grvga_mem_size = info->var.xres_virtual * info->var.yres_virtual * info->var.bits_per_pixel/8;
+
+	if (grvga_fix_addr) {
+		/* Got framebuffer base address from argument list */
+
+		physical_start = grvga_fix_addr;
+
+		if (!request_mem_region(physical_start, grvga_mem_size, dev->name)) {
+			dev_err(&dev->dev, "failed to request memory region\n");
+			retval = -ENOMEM;
+			goto err3;
+		}
+
+		virtual_start = (unsigned long) ioremap(physical_start, grvga_mem_size);
+
+		if (!virtual_start) {
+			dev_err(&dev->dev, "error mapping framebuffer memory\n");
+			retval = -ENOMEM;
+			goto err4;
+		}
+	} else {	/* Allocate frambuffer memory */
+
+		unsigned long page;
+
+		virtual_start = (unsigned long) __get_free_pages(GFP_DMA,
+								 get_order(grvga_mem_size));
+		if (!virtual_start) {
+			dev_err(&dev->dev,
+				"unable to allocate framebuffer memory (%lu bytes)\n",
+				grvga_mem_size);
+			retval = -ENOMEM;
+			goto err3;
+		}
+
+		physical_start = dma_map_single(&dev->dev, (void *)virtual_start, grvga_mem_size, DMA_TO_DEVICE);
+
+		/* Set page reserved so that mmap will work. This is necessary
+		 * since we'll be remapping normal memory.
+		 */
+		for (page = virtual_start;
+		     page < PAGE_ALIGN(virtual_start + grvga_mem_size);
+		     page += PAGE_SIZE) {
+			SetPageReserved(virt_to_page(page));
+		}
+
+		par->fb_alloced = 1;
+	}
+
+	memset((unsigned long *) virtual_start, 0, grvga_mem_size);
+
+	info->screen_base = (char __iomem *) virtual_start;
+	info->fix.smem_start = physical_start;
+	info->fix.smem_len   = grvga_mem_size;
+
+	dev_set_drvdata(&dev->dev, info);
+
+	dev_info(&dev->dev,
+		 "Aeroflex Gaisler framebuffer device (fb%d), %dx%d-%d, using %luK of video memory @ %p\n",
+		 info->node, info->var.xres, info->var.yres, info->var.bits_per_pixel,
+		 grvga_mem_size >> 10, info->screen_base);
+
+	retval = register_framebuffer(info);
+	if (retval < 0) {
+		dev_err(&dev->dev, "failed to register framebuffer\n");
+		goto err4;
+	}
+
+	__raw_writel(physical_start, &par->regs->fb_pos);
+	__raw_writel(__raw_readl(&par->regs->status) | 1,  /* Enable framebuffer */
+		     &par->regs->status);
+
+	return 0;
+
+err4:
+	dev_set_drvdata(&dev->dev, NULL);
+	if (grvga_fix_addr) {
+		release_mem_region(physical_start, grvga_mem_size);
+		iounmap((void *)virtual_start);
+	} else
+		kfree((void *)virtual_start);
+err3:
+	fb_dealloc_cmap(&info->cmap);
+err2:
+	of_iounmap(&dev->resource[0], par->regs,
+		   resource_size(&dev->resource[0]));
+err1:
+	release_mem_region(dev->resource[0].start, resource_size(&dev->resource[0]));
+err:
+	framebuffer_release(info);
+
+	return retval;
+}
+
+static int __devexit grvga_remove(struct platform_device *device)
+{
+	struct fb_info *info = dev_get_drvdata(&device->dev);
+	struct grvga_par *par = info->par;
+
+	if (info) {
+		unregister_framebuffer(info);
+		fb_dealloc_cmap(&info->cmap);
+
+		of_iounmap(&device->resource[0], par->regs,
+			   resource_size(&device->resource[0]));
+		release_mem_region(device->resource[0].start, resource_size(&device->resource[0]));
+
+		if (!par->fb_alloced) {
+			release_mem_region(info->fix.smem_start, info->fix.smem_len);
+			iounmap(info->screen_base);
+		} else
+			kfree((void *)info->screen_base);
+
+		framebuffer_release(info);
+		dev_set_drvdata(&device->dev, NULL);
+	}
+
+	return 0;
+}
+
+static struct of_device_id svgactrl_of_match[] = {
+	{
+		.name = "GAISLER_SVGACTRL",
+	},
+	{
+		.name = "01_063",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, svgactrl_of_match);
+
+static struct platform_driver grvga_driver = {
+	.driver = {
+		.name = "grlib-svgactrl",
+		.owner = THIS_MODULE,
+		.of_match_table = svgactrl_of_match,
+	},
+	.probe		= grvga_probe,
+	.remove		= __devexit_p(grvga_remove),
+};
+
+
+static int __init grvga_init(void)
+{
+	return platform_driver_register(&grvga_driver);
+}
+
+static void __exit grvga_exit(void)
+{
+	platform_driver_unregister(&grvga_driver);
+}
+
+module_init(grvga_init);
+module_exit(grvga_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Aeroflex Gaisler");
+MODULE_DESCRIPTION("Aeroflex Gaisler framebuffer device driver");
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 5/5] drivers/video/msm/mdp.c: adjust error handling code
From: Julia Lawall @ 2011-07-04 14:11 UTC (permalink / raw)
  To: David Brown
  Cc: kernel-janitors, Daniel Walker, Bryan Huntsman, Paul Mundt,
	linux-arm-msm, linux-fbdev, linux-kernel

From: Julia Lawall <julia@diku.dk>

Use the error handling code at the end of the function, rather than
returning directly.

The semantic match that finds this problem is as follows:
(http://coccinelle.lip6.fr/)

// <smpl>
@r@
identifier x;
@@

kfree(x)

@@
identifier r.x;
expression E1!=0,E2,E3,E4;
statement S;
@@

(
if (<+...x...+>) S
|
if (...) { ... when != kfree(x)
               when != if (...) { ... kfree(x); ... }
               when != x = E3
* return E1;
}
... when != x = E2
if (...) { ... when != x = E4
 kfree(x); ... return ...; }
)
// </smpl>

Signed-off-by: Julia Lawall <julia@diku.dk>

---
I wonder if the error handling code at the end of the function should be
calling clk_put as well?  In that case, having a separate label for this
case would be useful.  Otherwise, one of error_request_irq and error_get_clk
can be deleted

 drivers/video/msm/mdp.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 243d16f..01fa660 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -421,7 +421,8 @@ int mdp_probe(struct platform_device *pdev)
 	clk = clk_get(&pdev->dev, "mdp_clk");
 	if (IS_ERR(clk)) {
 		printk(KERN_INFO "mdp: failed to get mdp clk");
-		return PTR_ERR(clk);
+		ret = PTR_ERR(clk);
+		goto error_get_clk;
 	}
 
 	ret = request_irq(mdp->irq, mdp_isr, IRQF_DISABLED, "msm_mdp", mdp);
@@ -495,6 +496,7 @@ int mdp_probe(struct platform_device *pdev)
 error_device_register:
 	free_irq(mdp->irq, mdp);
 error_request_irq:
+error_get_clk:
 	iounmap(mdp->base);
 error_get_irq:
 error_ioremap:


^ permalink raw reply related

* [GIT PULL] fbdev fixes for 3.0-rc6
From: Paul Mundt @ 2011-07-04  8:21 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-fbdev, linux-kernel

Please pull from:

	master.kernel.org:/pub/scm/linux/kernel/git/lethal/fbdev-3.x.git fbdev-fixes-for-linus

Which contains:

Damian Hobson-Garcia (1):
      fbdev: sh_mobile_meram: Correct pointer check for YCbCr chroma plane

Daniel J Blueman (1):
      vesafb: fix memory leak

Loïc Minier (1):
      fbdev: amba: Link fb device to its parent

Pavel Shved (1):
      hecubafb: add module_put on error path in hecubafb_probe()

Randy Dunlap (2):
      gx1fb: Fix section mismatch warnings
      sm501fb: fix section mismatch warning

Timur Tabi (1):
      fsl-diu-fb: remove check for pixel clock ranges

William Katsak (1):
      udlfb: Correct sub-optimal resolution selection.

 drivers/video/amba-clcd.c        |    2 ++
 drivers/video/fsl-diu-fb.c       |   16 ----------------
 drivers/video/geode/gx1fb_core.c |   14 +++++++-------
 drivers/video/hecubafb.c         |    3 ++-
 drivers/video/sh_mobile_meram.c  |    2 +-
 drivers/video/sm501fb.c          |    2 +-
 drivers/video/udlfb.c            |    8 ++++++--
 drivers/video/vesafb.c           |    1 +
 include/linux/fsl-diu-fb.h       |    6 ------
 9 files changed, 20 insertions(+), 34 deletions(-)

^ permalink raw reply

* [PATCH 2/5 v4] fbdev: sh_mobile_meram: Enable/disable MERAM along with LCDC
From: Damian Hobson-Garcia @ 2011-07-04  8:06 UTC (permalink / raw)
  To: linux-fbdev

The MERAM reference counts should be tied to the two LCDC devices (LCD/HDMI)
so that when they are enable/disabled, the MERAM is as well.

Signed-off-by: Damian Hobson-Garcia <dhobsong@igel.co.jp>
---
Changes from V3
=======* Remove the MERAM callbacks used to runtime_get/runtime_put the device from
  the LCDC driver.  Instead, just call the functions on the MERAM device
  directly

 drivers/video/sh_mobile_lcdcfb.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 019dbd3..15e77f3 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -259,6 +259,8 @@ static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv)
 		pm_runtime_get_sync(priv->dev);
 		if (priv->dot_clk)
 			clk_enable(priv->dot_clk);
+		if (priv->meram_dev && priv->meram_dev->pdev)
+			pm_runtime_get_sync(&priv->meram_dev->pdev->dev);
 	}
 }
 
@@ -267,6 +270,8 @@ static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv)
 	if (atomic_sub_return(1, &priv->hw_usecnt) = -1) {
 		if (priv->dot_clk)
 			clk_disable(priv->dot_clk);
+		if (priv->meram_dev && priv->meram_dev->pdev)
+			pm_runtime_put_sync(&priv->meram_dev->pdev->dev);
 		pm_runtime_put(priv->dev);
 	}
 }
-- 
1.7.1


^ permalink raw reply related

* [PATCH 1/5] fbdev: sh_mobile_meram: Enable runtime PM
From: Damian Hobson-Garcia @ 2011-07-04  8:06 UTC (permalink / raw)
  To: linux-fbdev

Signed-off-by: Damian Hobson-Garcia <dhobsong@igel.co.jp>
---
 drivers/video/sh_mobile_meram.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c
index 9170c82..61e106f 100644
--- a/drivers/video/sh_mobile_meram.c
+++ b/drivers/video/sh_mobile_meram.c
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/device.h>
+#include <linux/pm_runtime.h>
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
@@ -515,6 +516,8 @@ static int __devinit sh_mobile_meram_probe(struct platform_device *pdev)
 	if (pdata->addr_mode = SH_MOBILE_MERAM_MODE1)
 		meram_write_reg(priv->base, MEVCR1, 1 << 29);
 
+	pm_runtime_enable(&pdev->dev);
+
 	dev_info(&pdev->dev, "sh_mobile_meram initialized.");
 
 	return 0;
@@ -530,6 +533,8 @@ static int sh_mobile_meram_remove(struct platform_device *pdev)
 {
 	struct sh_mobile_meram_priv *priv = platform_get_drvdata(pdev);
 
+	pm_runtime_disable(&pdev->dev);
+
 	if (priv->base)
 		iounmap(priv->base);
 
-- 
1.7.1


^ permalink raw reply related

* [PATCH 0/5 v4] LCDC MERAM runtime PM support
From: Damian Hobson-Garcia @ 2011-07-04  8:05 UTC (permalink / raw)
  To: linux-fbdev

This patch series is a provides PM runtime support for the LCDC MERAM.

The runtime_pm_get/put calls are made at the same time as the LCDC calls, so
that the LCDC MERAM is enabled with the first LCDC device and disabled 
with the last LCDC device.

The first 4 patches will apply to rmobile-latest or common/fbdev-meram as-is,
but the final patch needs to have the "PM / Domains: Support for generic I/O PM
domains" patch series. 

Only the first 2 patches of the series have been updated from v3 sent on
2011/06/22

Changes from V3

* Remove the MERAM callbacks used to runtime_get/runtime_put the device from
  the LCDC driver.  Instead, just call the functions on the MERAM device
  directly

Damian Hobson-Garcia (5):
  fbdev: sh_mobile_meram: Enable runtime PM
  fbdev: sh_mobile_meram: Enable/disable MERAM along with LCDC - v4
  fbdev: sh_mobile_meram: Move private data from .h to .c 
  fbdev: sh_mobile_meram: Backup/restore device registers on
    shutdown/resume - v3
  fbdev: sh_mobile_meram: Assign meram to the SH7372_A4LC power domain

 arch/arm/mach-shmobile/board-mackerel.c |    1 +
 drivers/video/sh_mobile_lcdcfb.c        |    6 ++
 drivers/video/sh_mobile_meram.c         |   84 +++++++++++++++++++++++++++++++
 drivers/video/sh_mobile_meram.h         |    8 ---
 4 files changed, 91 insertions(+), 8 deletions(-)


^ permalink raw reply

* [PATCH] video: backlight: fix const array syntax
From: Greg Dietsche @ 2011-07-01 22:47 UTC (permalink / raw)
  To: linux-fbdev

Correct the syntax so that both array and pointer are const.

Signed-off-by: Greg Dietsche <Gregory.Dietsche@cuw.edu>
---
 drivers/video/backlight/backlight.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 80d292f..4bda2e7 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -19,7 +19,7 @@
 #include <asm/backlight.h>
 #endif
 
-static const char const *backlight_types[] = {
+static const char * const backlight_types[] = {
 	[BACKLIGHT_RAW] = "raw",
 	[BACKLIGHT_PLATFORM] = "platform",
 	[BACKLIGHT_FIRMWARE] = "firmware",
-- 
1.7.2.5


^ permalink raw reply related

* Equity Business Investment
From: PROF.MAURICE IWU @ 2011-06-30 15:44 UTC (permalink / raw)
  To: linux-fbdev

Equity Business Investment
From Prof. Maurice Iwu 

Dear Friend,

I am Prof. Maurice M. Iwu, Former Chairman Independent Electoral Commission 
(INEC).Currently, I am on compulsory terminal leave presently in UK , 
leading up to my final retirement from public service.

I am seeking your partnership in a mutual benefit project involving 
investing into your company and secondly on properties and to be precise Estate Development or any other profitable venture of your great idea for our mutual benefit of Equity Market Investment.,

Sincerely,
Prof. Maurice M.Iwu.
{INEC.}

^ permalink raw reply

* Re: [uclinux-dist-devel] [PATCH] fbdev: bfin_adv7393fb: convert to seq_file
From: Mike Frysinger @ 2011-06-29 21:05 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1309213715-31842-1-git-send-email-vapier@gentoo.org>

On Mon, Jun 27, 2011 at 18:28, Mike Frysinger wrote:
> ->read_proc and ->write_proc interfaces are going away,
> switch to seq_file/->write().

actually, let's not merge this.  it has build errors:
drivers/video/bfin_adv7393fb.c:364: error: ‘adv7393_proc_write’
undeclared here (not in a function)

the code originally had "adv7393_write_proc", but the new code refers
to "adv7393fb_proc_write".  also, file_operations.write does not take
the same arguments as proc_dir_entry.write.  so this needs a little
more love than renaming the func.
-mike

^ permalink raw reply

* Re: [PATCH] OMAP: DSS: dispc: enable/disable clocks in error handler
From: Archit Taneja @ 2011-06-29 17:02 UTC (permalink / raw)
  To: Valkeinen, Tomi
  Cc: Taneja, Archit, Dima Zavin, linux-fbdev@vger.kernel.org,
	linux-omap@vger.kernel.org
In-Reply-To: <1309323487.1829.9.camel@deskari>

Hi,

On Tuesday 28 June 2011 09:58 PM, Valkeinen, Tomi wrote:
> On Tue, 2011-06-28 at 09:19 -0700, Archit Taneja wrote:
>> Hi,
>>
>> On Monday 27 June 2011 10:31 AM, Dima Zavin wrote:
>>> There's no guarantee that the error handler worker thread
>>> will run while the dispc clocks are on. Explicitly enable/disable
>>> them.
>>
>> I agree with this.
>
> Yes, I think this patch is fine. I'll apply it to DSS tree.
>
>> Tomi,
>>
>> We could get prevent scheduling of the error worker by registering
>> omap_dispc_irq_handler() as an interrupt thread.
>
> But then we would get extra latency on the interrupt handlers. I wanted
> to keep handling DSS interrupts in interrupt context, because some use
> cases may require very fast reaction to an interrupt.

Okay..we don't need to handle the errors in interrupt context..the 
request_threaded_irq() takes 2 functions I think, we could have have 
omap_dispc_irq_handler() as the primary handler, and the error_worker as 
the thread.

I think the change I'm just suggesting just leads to some beautification 
in the end :), we would still need to ensure that clocks are enabled in 
the error_worker path.

Archit



^ permalink raw reply

* RE: [PATCH V7 5/5] ARM: EXYNOS4: Add platform data for EXYNOS4 FIMD
From: Kukjin Kim @ 2011-06-29 13:58 UTC (permalink / raw)
  To: 'Jingoo Han', 'Paul Mundt', linux-samsung-soc,
	linux-fbdev
  Cc: 'Anand Kumar N', 'Thomas Abraham',
	'Sylwester Nawrocki', 'Marek Szyprowski',
	'Kyungmin Park', 'Inki Dae', 'ARM Linux',
	'Ben Dooks', 'Jonghun Han'
In-Reply-To: <1309171858-30397-1-git-send-email-jg1.han@samsung.com>

Jingoo Han wrote:
> 
> From: Jonghun Han <jonghun.han@samsung.com>
> 
> This patch adds support EXYNOS4 FIMD0 and LTE480WV LCD pannel.
> 
> Signed-off-by: Jonghun Han <jonghun.han@samsung.com>
> Signed-off-by: Jingoo Han <jg1.han@samsung.com>
> ---
>  arch/arm/mach-exynos4/mach-smdkc210.c |   71
> +++++++++++++++++++++++++++++++++
>  arch/arm/mach-exynos4/mach-smdkv310.c |   71
> +++++++++++++++++++++++++++++++++
>  2 files changed, 142 insertions(+), 0 deletions(-)
> 
As I said, don't push same codes into both.

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.


^ permalink raw reply

* RE: [PATCH] video: da8xx-fb: Interrupt configuration of revised
From: Manjunathappa, Prakash @ 2011-06-29 12:31 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1309150507-32512-1-git-send-email-prakash.pm@ti.com>

Hi All,

I have found couple of below minor nits. Hence I am planning to submit version 2 of this patch. Please let me know if you have any other comments?

Thanks,
Prakash

On Mon, Jun 27, 2011 at 10:25:07, Manjunathappa, Prakash wrote:
> Interrupt configuration support for revised LCDC IP of DA850 in
> upcoming SOC from TI.
> The revised LCDC IP differs in interrupt configuration; registers
> for setting and clearing interrupts, raw and masked status registers
> to depict raw and enabled interrupts status.
> 
> Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
> ---
>  drivers/video/da8xx-fb.c |  153 +++++++++++++++++++++++++++++++++++++++++++---
>  1 files changed, 144 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
> index fcdac87..0e02665 100644
> --- a/drivers/video/da8xx-fb.c
> +++ b/drivers/video/da8xx-fb.c
> @@ -35,6 +35,9 @@
>  
>  #define DRIVER_NAME "da8xx_lcdc"
>  
> +#define LCD_VERSION_1	1
> +#define LCD_VERSION_2	2
> +
>  /* LCD Status Register */
>  #define LCD_END_OF_FRAME1		BIT(9)
>  #define LCD_END_OF_FRAME0		BIT(8)
> @@ -49,7 +52,9 @@
>  #define LCD_DMA_BURST_4			0x2
>  #define LCD_DMA_BURST_8			0x3
>  #define LCD_DMA_BURST_16		0x4
> -#define LCD_END_OF_FRAME_INT_ENA	BIT(2)
> +#define LCD_V1_END_OF_FRAME_INT_ENA	BIT(2)
> +#define LCD_V2_END_OF_FRAME0_INT_ENA	BIT(8)
> +#define LCD_V2_END_OF_FRAME1_INT_ENA	BIT(9)
>  #define LCD_DUAL_FRAME_BUFFER_ENABLE	BIT(0)
>  
>  /* LCD Control Register */
> @@ -65,12 +70,18 @@
>  #define LCD_MONO_8BIT_MODE		BIT(9)
>  #define LCD_RASTER_ORDER		BIT(8)
>  #define LCD_TFT_MODE			BIT(7)
> -#define LCD_UNDERFLOW_INT_ENA		BIT(6)
> -#define LCD_PL_ENABLE			BIT(4)
> +#define LCD_V1_UNDERFLOW_INT_ENA	BIT(6)
> +#define LCD_V2_UNDERFLOW_INT_ENA	BIT(5)
> +#define LCD_V1_PL_INT_ENA		BIT(4)
> +#define LCD_V2_PL_INT_ENA		BIT(6)
>  #define LCD_MONOCHROME_MODE		BIT(1)
>  #define LCD_RASTER_ENABLE		BIT(0)
>  #define LCD_TFT_ALT_ENABLE		BIT(23)
>  #define LCD_STN_565_ENABLE		BIT(24)
> +#define LCD_V2_DMA_CLK_EN		BIT(2)
> +#define LCD_V2_LIDD_CLK_EN		BIT(1)
> +#define LCD_V2_CORE_CLK_EN		BIT(0)
> +#define LCD_V2_LPP_B10			26
>  
>  /* LCD Raster Timing 2 Register */
>  #define LCD_AC_BIAS_TRANSITIONS_PER_INT(x)	((x) << 16)
> @@ -82,6 +93,7 @@
>  #define LCD_INVERT_FRAME_CLOCK			BIT(20)
>  
>  /* LCD Block */
> +#define  LCD_PID_REG				0x0
>  #define  LCD_CTRL_REG				0x4
>  #define  LCD_STAT_REG				0x8
>  #define  LCD_RASTER_CTRL_REG			0x28
> @@ -94,6 +106,17 @@
>  #define  LCD_DMA_FRM_BUF_BASE_ADDR_1_REG	0x4C
>  #define  LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG	0x50
>  
> +/* Interrupt Registers available only in Version 2 */
> +#define  LCD_RAW_STAT_REG			0x58
> +#define  LCD_MASKED_STAT_REG			0x5c
> +#define  LCD_INT_ENABLE_SET_REG			0x60
> +#define  LCD_INT_ENABLE_CLR_REG			0x64
> +#define  LCD_END_OF_INT_IND_REG			0x68
> +
> +/* Clock registers available only on Version 2 */
> +#define  LCD_CLK_ENABLE_REG			0x6c
> +#define  LCD_CLK_RESET_REG			0x70
> +
>  #define LCD_NUM_BUFFERS	2
>  
>  #define WSI_TIMEOUT	50
> @@ -105,6 +128,8 @@
>  
>  static resource_size_t da8xx_fb_reg_base;
>  static struct resource *lcdc_regs;
> +static unsigned int lcd_revision;
> +static irq_handler_t lcdc_irq_handler;
>  
>  static inline unsigned int lcdc_read(unsigned int addr)
>  {
> @@ -240,6 +265,7 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
>  	u32 end;
>  	u32 reg_ras;
>  	u32 reg_dma;
> +	u32 reg_int;
>  
>  	/* init reg to clear PLM (loading mode) fields */
>  	reg_ras = lcdc_read(LCD_RASTER_CTRL_REG);
> @@ -252,7 +278,14 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
>  		end      = par->dma_end;
>  
>  		reg_ras |= LCD_PALETTE_LOAD_MODE(DATA_ONLY);
> -		reg_dma |= LCD_END_OF_FRAME_INT_ENA;
> +		if (lcd_revision = LCD_VERSION_1) {
> +			reg_dma |= LCD_V1_END_OF_FRAME_INT_ENA;
> +		} else {
> +			reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
> +				LCD_V2_END_OF_FRAME0_INT_ENA |
> +				LCD_V2_END_OF_FRAME1_INT_ENA;
> +			lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
> +		}
>  		reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE;
>  
>  		lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
> @@ -264,7 +297,14 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
>  		end      = start + par->palette_sz - 1;
>  
>  		reg_ras |= LCD_PALETTE_LOAD_MODE(PALETTE_ONLY);
> -		reg_ras |= LCD_PL_ENABLE;
> +
> +		if (lcd_revision = LCD_VERSION_1) {
> +			reg_ras |= LCD_V1_PL_INT_ENA;
> +		} else {
> +			reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
> +				LCD_V2_PL_INT_ENA;
> +			lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
> +		}
>  
>  		lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
>  		lcdc_write(end, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
> @@ -348,6 +388,7 @@ static void lcd_cfg_vertical_sync(int back_porch, int pulse_width,
>  static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
>  {
>  	u32 reg;
> +	u32 reg_int;
>  
>  	reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(LCD_TFT_MODE |
>  						LCD_MONO_8BIT_MODE |
> @@ -375,7 +416,13 @@ static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
>  	}
>  
>  	/* enable additional interrupts here */
> -	reg |= LCD_UNDERFLOW_INT_ENA;
> +	if (lcd_revision = LCD_VERSION_1) {
> +		reg |= LCD_V1_UNDERFLOW_INT_ENA;
> +	} else {
> +		reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
> +		       (LCD_V2_UNDERFLOW_INT_ENA);
		 	 ^				  ^
[Prakash] I will remove above marked braces.

> +		lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
> +	}
>  
>  	lcdc_write(reg, LCD_RASTER_CTRL_REG);
>  
> @@ -415,12 +462,14 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
>  	/* Pixels per line = (PPL + 1)*16 */
>  	/*0x3F in bits 4..9 gives max horisontal resolution = 1024 pixels*/
>  	width &= 0x3f0;
> +
[Prakash] Will remove random white space.
>  	reg = lcdc_read(LCD_RASTER_TIMING_0_REG);
>  	reg &= 0xfffffc00;
>  	reg |= ((width >> 4) - 1) << 4;
>  	lcdc_write(reg, LCD_RASTER_TIMING_0_REG);
>  
>  	/* Set the Panel Height */
> +
[Prakash] Will remove random white space.
>  	reg = lcdc_read(LCD_RASTER_TIMING_1_REG);
>  	reg = ((height - 1) & 0x3ff) | (reg & 0xfffffc00);
>  	lcdc_write(reg, LCD_RASTER_TIMING_1_REG);
> @@ -511,6 +560,9 @@ static void lcd_reset(struct da8xx_fb_par *par)
>  	/* DMA has to be disabled */
>  	lcdc_write(0, LCD_DMA_CTRL_REG);
>  	lcdc_write(0, LCD_RASTER_CTRL_REG);
> +
> +	if (lcd_revision = LCD_VERSION_2)
> +		lcdc_write(0, LCD_INT_ENABLE_SET_REG);
>  }
>  
>  static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
> @@ -523,6 +575,11 @@ static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
>  	/* Configure the LCD clock divisor. */
>  	lcdc_write(LCD_CLK_DIVISOR(div) |
>  			(LCD_RASTER_MODE & 0x1), LCD_CTRL_REG);
> +
> +	if (lcd_revision = LCD_VERSION_2)
> +		lcdc_write(LCD_V2_DMA_CLK_EN | LCD_V2_LIDD_CLK_EN |
> +				LCD_V2_CORE_CLK_EN, LCD_CLK_ENABLE_REG);
> +
>  }
>  
>  static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
> @@ -583,7 +640,63 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
>  	return 0;
>  }
>  
> -static irqreturn_t lcdc_irq_handler(int irq, void *arg)
> +/* IRQ handler for version 2 of LCDC */
> +static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
> +{
> +	struct da8xx_fb_par *par = arg;
> +	u32 stat = lcdc_read(LCD_MASKED_STAT_REG);
> +	u32 reg_int;
> +
> +	if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
> +		lcd_disable_raster();
> +		lcdc_write(stat, LCD_MASKED_STAT_REG);
> +		lcd_enable_raster();
> +	} else if (stat & LCD_PL_LOAD_DONE) {
> +		/*
> +		 * Must disable raster before changing state of any control bit.
> +		 * And also must be disabled before clearing the PL loading
> +		 * interrupt via the following write to the status register. If
> +		 * this is done after then one gets multiple PL done interrupts.
> +		 */
> +		lcd_disable_raster();
> +
> +		lcdc_write(stat, LCD_MASKED_STAT_REG);
> +
> +		/* Disable PL completion inerrupt */
> +		reg_int = lcdc_read(LCD_INT_ENABLE_CLR_REG) |
> +		       (LCD_V2_PL_INT_ENA);
> +		lcdc_write(reg_int, LCD_INT_ENABLE_CLR_REG);
> +
> +		/* Setup and start data loading mode */
> +		lcd_blit(LOAD_DATA, par);
> +	} else {
> +		lcdc_write(stat, LCD_MASKED_STAT_REG);
> +
> +		if (stat & LCD_END_OF_FRAME0) {
> +			lcdc_write(par->dma_start,
> +				   LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
> +			lcdc_write(par->dma_end,
> +				   LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
> +			par->vsync_flag = 1;
> +			wake_up_interruptible(&par->vsync_wait);
> +		}
> +
> +		if (stat & LCD_END_OF_FRAME1) {
> +			lcdc_write(par->dma_start,
> +				   LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
> +			lcdc_write(par->dma_end,
> +				   LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
> +			par->vsync_flag = 1;
> +			wake_up_interruptible(&par->vsync_wait);
> +		}
> +	}
> +
> +	lcdc_write(0, LCD_END_OF_INT_IND_REG);
> +	return IRQ_HANDLED;
> +}
> +
> +/* IRQ handler for version 1 LCDC */
> +static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
>  {
>  	struct da8xx_fb_par *par = arg;
>  	u32 stat = lcdc_read(LCD_STAT_REG);
> @@ -606,7 +719,7 @@ static irqreturn_t lcdc_irq_handler(int irq, void *arg)
>  
>  		/* Disable PL completion inerrupt */
>  		reg_ras  = lcdc_read(LCD_RASTER_CTRL_REG);
> -		reg_ras &= ~LCD_PL_ENABLE;
> +		reg_ras &= ~LCD_V1_PL_INT_ENA;
>  		lcdc_write(reg_ras, LCD_RASTER_CTRL_REG);
>  
>  		/* Setup and start data loading mode */
> @@ -945,6 +1058,22 @@ static int __devinit fb_probe(struct platform_device *device)
>  	if (ret)
>  		goto err_clk_put;
>  
> +	/* Determine LCD IP Version */
> +	switch (lcdc_read(LCD_PID_REG)) {
> +	case 0x4C100102:
> +		lcd_revision = LCD_VERSION_1;
> +		break;
> +	case 0x4F200800:
> +		lcd_revision = LCD_VERSION_2;
> +		break;
> +	default:
> +		dev_warn(&device->dev, "Unknown PID Reg value 0x%x, "
> +				"defaulting to LCD revision 1\n",
> +				lcdc_read(LCD_PID_REG));
> +		lcd_revision = LCD_VERSION_1;
> +		break;
> +	}
> +
>  	for (i = 0, lcdc_info = known_lcd_panels;
>  		i < ARRAY_SIZE(known_lcd_panels);
>  		i++, lcdc_info++) {
> @@ -1085,7 +1214,13 @@ static int __devinit fb_probe(struct platform_device *device)
>  	}
>  #endif
>  
> -	ret = request_irq(par->irq, lcdc_irq_handler, 0, DRIVER_NAME, par);
> +	if (lcd_revision = LCD_VERSION_1)
> +		lcdc_irq_handler = lcdc_irq_handler_rev01;
> +	else
> +		lcdc_irq_handler = lcdc_irq_handler_rev02;
> +
> +	ret = request_irq(par->irq, lcdc_irq_handler, 0,
> +			DRIVER_NAME, par);
>  	if (ret)
>  		goto irq_freq;
>  	return 0;
> -- 
> 1.7.1
> 
> 


^ permalink raw reply

* Re: [PATCH 1/5 v3] fbdev: sh_mobile_meram: Add enable/disble hooks
From: Damian Hobson-Garcia @ 2011-06-29  5:26 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1308728992-9660-2-git-send-email-dhobsong@igel.co.jp>

Hi Paul,

On 2011/06/24 14:34, Paul Mundt wrote:
> On Wed, Jun 22, 2011 at 04:49:48PM +0900, Damian Hobson-Garcia wrote:
>> +static int sh_mobile_meram_pm_get_sync(struct sh_mobile_meram_info *pdata)
>> +{
>> +	if (!pdata || !pdata->pdev)
>> +		return -EINVAL;
>> +
>> +	dev_dbg(&pdata->pdev->dev, "Enabling sh_mobile_meram clock.");
>> +	pm_runtime_get_sync(&pdata->pdev->dev);
>> +	return 0;
>> +}
>> +
> 
> On Wed, Jun 22, 2011 at 04:49:49PM +0900, Damian Hobson-Garcia wrote:
>> @@ -259,6 +259,11 @@ static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv)
>>  		pm_runtime_get_sync(priv->dev);
>>  		if (priv->dot_clk)
>>  			clk_enable(priv->dot_clk);
>> +		if (priv->meram_dev && priv->meram_dev->ops) {
>> +			struct sh_mobile_meram_info *mdev;
>> +			mdev = priv->meram_dev;
>> +			mdev->ops->meram_pm_get_sync(mdev);
>> +		}
>>  	}
>>  }
>>  
> I'm not sure that I really see the point in the callbacks. The callbacks
> would make sense in the case where you're dealing with opaque types that
> you don't wish to have knowledge of in the other drivers, but when all
> you're doing is fetching the pointer and wrapping verbatim in to the
> runtime pm calls, it just seems like a pointless layer of indirection.
> 
> You could easily just do this as:
> 
> 	if (priv->meram_dev)
> 		pm_runtime_get_sync(&priv->meram_dev->pdev->dev);
> 
> and be done with it.
> 
> This will also save you from having to add additional callbacks should
> you decide that you suddenly require async behaviour or so in other
> cases, too.
Thanks for your comment.

You raise a good point here.  I'll get rid of the useless call.

Damian

^ permalink raw reply

* Re: [PATCH] OMAP: DSS: dispc: enable/disable clocks in error
From: Tomi Valkeinen @ 2011-06-29  4:58 UTC (permalink / raw)
  To: Archit Taneja
  Cc: Dima Zavin, linux-fbdev@vger.kernel.org,
	linux-omap@vger.kernel.org
In-Reply-To: <4E09FEFD.9020005@ti.com>

On Tue, 2011-06-28 at 09:19 -0700, Archit Taneja wrote:
> Hi,
> 
> On Monday 27 June 2011 10:31 AM, Dima Zavin wrote:
> > There's no guarantee that the error handler worker thread
> > will run while the dispc clocks are on. Explicitly enable/disable
> > them.
> 
> I agree with this.

Yes, I think this patch is fine. I'll apply it to DSS tree.

> Tomi,
> 
> We could get prevent scheduling of the error worker by registering 
> omap_dispc_irq_handler() as an interrupt thread.

But then we would get extra latency on the interrupt handlers. I wanted
to keep handling DSS interrupts in interrupt context, because some use
cases may require very fast reaction to an interrupt.

 Tomi



^ permalink raw reply

* Re: [PATCH] OMAP: DSS: dispc: enable/disable clocks in error handler
From: Archit Taneja @ 2011-06-28 16:19 UTC (permalink / raw)
  To: Dima Zavin
  Cc: Valkeinen, Tomi, linux-fbdev@vger.kernel.org,
	linux-omap@vger.kernel.org
In-Reply-To: <1309195865-23808-1-git-send-email-dima@android.com>

Hi,

On Monday 27 June 2011 10:31 AM, Dima Zavin wrote:
> There's no guarantee that the error handler worker thread
> will run while the dispc clocks are on. Explicitly enable/disable
> them.

I agree with this.

Tomi,

We could get prevent scheduling of the error worker by registering 
omap_dispc_irq_handler() as an interrupt thread.

Archit

>
> Signed-off-by: Dima Zavin<dima@android.com>
> ---
>   drivers/video/omap2/dss/dispc.c |    4 ++++
>   1 files changed, 4 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
> index 62aa77c..2458248 100644
> --- a/drivers/video/omap2/dss/dispc.c
> +++ b/drivers/video/omap2/dss/dispc.c
> @@ -3292,6 +3292,8 @@ static void dispc_error_worker(struct work_struct *work)
>   	dispc.error_irqs = 0;
>   	spin_unlock_irqrestore(&dispc.irq_lock, flags);
>
> +	dispc_runtime_get();
> +
>   	if (errors&  DISPC_IRQ_GFX_FIFO_UNDERFLOW) {
>   		DSSERR("GFX_FIFO_UNDERFLOW, disabling GFX\n");
>   		for (i = 0; i<  omap_dss_get_num_overlays(); ++i) {
> @@ -3478,6 +3480,8 @@ static void dispc_error_worker(struct work_struct *work)
>   	dispc.irq_error_mask |= errors;
>   	_omap_dispc_set_irqs();
>   	spin_unlock_irqrestore(&dispc.irq_lock, flags);
> +
> +	dispc_runtime_put();
>   }
>
>   int omap_dispc_wait_for_irq_timeout(u32 irqmask, unsigned long timeout)


^ permalink raw reply

* [PATCH] video: update author email for atmel-pwm-bl backlight driver
From: Hans-Christian Egtvedt @ 2011-06-28 15:05 UTC (permalink / raw)
  To: linux-fbdev

This patch updates the email address of the atmel-pwm-bl backlight driver
supported by me to an email account I will use on a more regular basis in the
future.

Signed-off-by: Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com>
---
 drivers/video/backlight/atmel-pwm-bl.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c
index 0443a4f..7c6a88a 100644
--- a/drivers/video/backlight/atmel-pwm-bl.c
+++ b/drivers/video/backlight/atmel-pwm-bl.c
@@ -243,6 +243,6 @@ static void __exit atmel_pwm_bl_exit(void)
 }
 module_exit(atmel_pwm_bl_exit);
 
-MODULE_AUTHOR("Hans-Christian egtvedt <hans-christian.egtvedt@atmel.com>");
+MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>");
 MODULE_DESCRIPTION("Atmel PWM backlight driver");
 MODULE_LICENSE("GPL");
-- 
1.7.4.1


^ permalink raw reply related

* Re: [PATCH v2 05/29] atmel_lcdfb: use display information in info
From: Wolfram Sang @ 2011-06-28  9:13 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1308043507-11083-6-git-send-email-laurent.pinchart@ideasonboard.com>

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

> > ------------------------^^^
> > Wolfram Sang identified this error: it cannot compile!
> > Thank you Wolfram.
> 
> Oops, sorry for that.

Thanks for fixing the issue :)

> > *When* the error will be corrected, you can submit it to linux-fbdev
> > with my:
> > 
> > Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
> 
> Thank you. I will resubmit fixed patches with your ack.

And my

Reviewed-by: Wolfram Sang <w.sang@pengutronix.de>

-- 
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply

* Re: [PATCH v2 05/29] atmel_lcdfb: use display information in info not in var for panning
From: Laurent Pinchart @ 2011-06-28  9:09 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1308043507-11083-6-git-send-email-laurent.pinchart@ideasonboard.com>

Hi Nicolas,

On Tuesday 28 June 2011 10:10:13 Nicolas Ferre wrote:
> Le 14/06/2011 11:24, Laurent Pinchart :
> > We must not use any information in the passed var besides xoffset,
> > yoffset and vmode as otherwise applications might abuse it.
> > 
> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
> > ---
> > 
> >  drivers/video/atmel_lcdfb.c |   15 +++++++++------
> >  1 files changed, 9 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
> > index 4484c72..8b5d755 100644
> > --- a/drivers/video/atmel_lcdfb.c
> > +++ b/drivers/video/atmel_lcdfb.c
> > @@ -39,7 +39,8 @@
> > 
> >  					 | FBINFO_HWACCEL_YPAN)
> >  
> >  static inline void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info
> >  *sinfo,
> > 
> > -					struct fb_var_screeninfo *var)
> > +					struct fb_var_screeninfo *var,
> > +					struct fb_info *info)
> > 
> >  {
> >  
> >  }
> > 
> > @@ -50,14 +51,16 @@ static inline void atmel_lcdfb_update_dma2d(struct
> > atmel_lcdfb_info *sinfo,
> > 
> >  					| FBINFO_HWACCEL_YPAN)
> >  
> >  static void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
> > 
> > -				     struct fb_var_screeninfo *var)
> > +				     struct fb_var_screeninfo *var,
> > +				     struct fb_info *info)
> > 
> >  {
> >  
> >  	u32 dma2dcfg;
> >  	u32 pixeloff;
> > 
> > -	pixeloff = (var->xoffset * var->bits_per_pixel) & 0x1f;
> > +	pixeloff = (var->xoffset * info->var.bits_per_pixel) & 0x1f;
> > 
> > -	dma2dcfg = ((var->xres_virtual - var->xres) * var->bits_per_pixel) / 8;
> > +	dma2dcfg = (info-var.xres_virtual - info->var.xres)
> 
> ------------------------^^^
> Wolfram Sang identified this error: it cannot compile!
> Thank you Wolfram.

Oops, sorry for that.

> > +		 * info->var.bits_per_pixel / 8;
> > 
> >  	dma2dcfg |= pixeloff << ATMEL_LCDC_PIXELOFF_OFFSET;
> >  	lcdc_writel(sinfo, ATMEL_LCDC_DMA2DCFG, dma2dcfg);
> > 
> > @@ -249,14 +252,14 @@ static void atmel_lcdfb_update_dma(struct fb_info
> > *info,
> > 
> >  	unsigned long dma_addr;
> >  	
> >  	dma_addr = (fix->smem_start + var->yoffset * fix->line_length
> > 
> > -		    + var->xoffset * var->bits_per_pixel / 8);
> > +		    + var->xoffset * info->var.bits_per_pixel / 8);
> > 
> >  	dma_addr &= ~3UL;
> >  	
> >  	/* Set framebuffer DMA base address and pixel offset */
> >  	lcdc_writel(sinfo, ATMEL_LCDC_DMABADDR1, dma_addr);
> > 
> > -	atmel_lcdfb_update_dma2d(sinfo, var);
> > +	atmel_lcdfb_update_dma2d(sinfo, var, info);
> > 
> >  }
> >  
> >  static inline void atmel_lcdfb_free_video_memory(struct atmel_lcdfb_info
> >  *sinfo)
> 
> *When* the error will be corrected, you can submit it to linux-fbdev
> with my:
> 
> Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>

Thank you. I will resubmit fixed patches with your ack.

-- 
Regards,

Laurent Pinchart

^ permalink raw reply

* Re: [PATCH v2 05/29] atmel_lcdfb: use display information in info
From: Nicolas Ferre @ 2011-06-28  8:10 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1308043507-11083-6-git-send-email-laurent.pinchart@ideasonboard.com>

Laurent,

Le 14/06/2011 11:24, Laurent Pinchart :
> We must not use any information in the passed var besides xoffset,
> yoffset and vmode as otherwise applications might abuse it.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
> ---
>  drivers/video/atmel_lcdfb.c |   15 +++++++++------
>  1 files changed, 9 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
> index 4484c72..8b5d755 100644
> --- a/drivers/video/atmel_lcdfb.c
> +++ b/drivers/video/atmel_lcdfb.c
> @@ -39,7 +39,8 @@
>  					 | FBINFO_HWACCEL_YPAN)
>  
>  static inline void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
> -					struct fb_var_screeninfo *var)
> +					struct fb_var_screeninfo *var,
> +					struct fb_info *info)
>  {
>  
>  }
> @@ -50,14 +51,16 @@ static inline void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
>  					| FBINFO_HWACCEL_YPAN)
>  
>  static void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
> -				     struct fb_var_screeninfo *var)
> +				     struct fb_var_screeninfo *var,
> +				     struct fb_info *info)
>  {
>  	u32 dma2dcfg;
>  	u32 pixeloff;
>  
> -	pixeloff = (var->xoffset * var->bits_per_pixel) & 0x1f;
> +	pixeloff = (var->xoffset * info->var.bits_per_pixel) & 0x1f;
>  
> -	dma2dcfg = ((var->xres_virtual - var->xres) * var->bits_per_pixel) / 8;
> +	dma2dcfg = (info-var.xres_virtual - info->var.xres)

------------------------^^^
Wolfram Sang identified this error: it cannot compile!
Thank you Wolfram.

> +		 * info->var.bits_per_pixel / 8;
>  	dma2dcfg |= pixeloff << ATMEL_LCDC_PIXELOFF_OFFSET;
>  	lcdc_writel(sinfo, ATMEL_LCDC_DMA2DCFG, dma2dcfg);
>  
> @@ -249,14 +252,14 @@ static void atmel_lcdfb_update_dma(struct fb_info *info,
>  	unsigned long dma_addr;
>  
>  	dma_addr = (fix->smem_start + var->yoffset * fix->line_length
> -		    + var->xoffset * var->bits_per_pixel / 8);
> +		    + var->xoffset * info->var.bits_per_pixel / 8);
>  
>  	dma_addr &= ~3UL;
>  
>  	/* Set framebuffer DMA base address and pixel offset */
>  	lcdc_writel(sinfo, ATMEL_LCDC_DMABADDR1, dma_addr);
>  
> -	atmel_lcdfb_update_dma2d(sinfo, var);
> +	atmel_lcdfb_update_dma2d(sinfo, var, info);
>  }
>  
>  static inline void atmel_lcdfb_free_video_memory(struct atmel_lcdfb_info *sinfo)


*When* the error will be corrected, you can submit it to linux-fbdev
with my:

Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>

Thanks, best regards,
-- 
Nicolas Ferre


^ permalink raw reply

* [PATCH] vesafb: fix memory leak
From: Daniel J Blueman @ 2011-06-27 23:08 UTC (permalink / raw)
  To: Paul Mundt; +Cc: linux-fbdev, linux-kernel, Daniel J Blueman

When releasing framebuffer, free colourmap allocations.

Signed-off-by: Daniel J Blueman <daniel.blueman@gmail.com>
---
 drivers/video/vesafb.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index a99bbe8..501b340 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -175,6 +175,7 @@ static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
 
 static void vesafb_destroy(struct fb_info *info)
 {
+	fb_dealloc_cmap(&info->cmap);
 	if (info->screen_base)
 		iounmap(info->screen_base);
 	release_mem_region(info->apertures->ranges[0].base, info->apertures->ranges[0].size);
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH] fbdev: bfin_adv7393fb: convert to seq_file
From: Mike Frysinger @ 2011-06-27 22:28 UTC (permalink / raw)
  To: linux-fbdev

From: Alexey Dobriyan <adobriyan@gmail.com>

->read_proc and ->write_proc interfaces are going away,
switch to seq_file/->write().

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
 drivers/video/bfin_adv7393fb.c |   44 ++++++++++++++-------------------------
 1 files changed, 16 insertions(+), 28 deletions(-)

diff --git a/drivers/video/bfin_adv7393fb.c b/drivers/video/bfin_adv7393fb.c
index 8486f54..ac19284 100644
--- a/drivers/video/bfin_adv7393fb.c
+++ b/drivers/video/bfin_adv7393fb.c
@@ -35,6 +35,7 @@
 
 #include <linux/dma-mapping.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/platform_device.h>
 
 #include <linux/i2c.h>
@@ -322,42 +323,25 @@ static irqreturn_t ppi_irq_error(int irq, void *dev_id)
 
 }
 
-static int proc_output(char *buf)
+static int adv7393_proc_show(struct seq_file *m, void *v)
 {
-	char *p = buf;
-
-	p += sprintf(p,
+	return seq_puts(m,
 		"Usage:\n"
 		"echo 0x[REG][Value] > adv7393\n"
 		"example: echo 0x1234 >adv7393\n"
 		"writes 0x34 into Register 0x12\n");
-
-	return p - buf;
 }
 
-static int
-adv7393_read_proc(char *page, char **start, off_t off,
-		  int count, int *eof, void *data)
+static int adv7393_proc_open(struct inode *inode, struct file *file)
 {
-	int len;
-
-	len = proc_output(page);
-	if (len <= off + count)
-		*eof = 1;
-	*start = page + off;
-	len -= off;
-	if (len > count)
-		len = count;
-	if (len < 0)
-		len = 0;
-	return len;
+	return single_open(file, adv7393_proc_show, NULL);
 }
 
 static int
 adv7393_write_proc(struct file *file, const char __user * buffer,
 		   unsigned long count, void *data)
 {
-	struct adv7393fb_device *fbdev = data;
+	struct adv7393fb_device *fbdev = PDE(file->f_path.dentry->d_inode)->data;
 	char line[8];
 	unsigned int val;
 	int ret;
@@ -372,6 +356,14 @@ adv7393_write_proc(struct file *file, const char __user * buffer,
 	return count;
 }
 
+static const struct file_operations adv7393_proc_ops = {
+	.open		= adv7393_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= adv7393_proc_write,
+};
+
 static int __devinit bfin_adv7393_fb_probe(struct i2c_client *client,
 					   const struct i2c_device_id *id)
 {
@@ -509,17 +501,13 @@ static int __devinit bfin_adv7393_fb_probe(struct i2c_client *client,
 	       fbdev->info.node, fbdev->info.fix.id);
 	dev_info(&client->dev, "fb memory address : 0x%p\n", fbdev->fb_mem);
 
-	entry = create_proc_entry("driver/adv7393", 0, NULL);
+	entry = proc_create_data("driver/adv7393", 0, NULL,
+				 &adv7393_proc_ops, fbdev);
 	if (!entry) {
 		dev_err(&client->dev, "unable to create /proc entry\n");
 		ret = -EFAULT;
 		goto out_0;
 	}
-
-	entry->read_proc = adv7393_read_proc;
-	entry->write_proc = adv7393_write_proc;
-	entry->data = fbdev;
-
 	return 0;
 
  out_0:
-- 
1.7.5.3


^ permalink raw reply related

* [PATCH] OMAP: DSS: dispc: enable/disable clocks in error handler
From: Dima Zavin @ 2011-06-27 17:31 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, Dima Zavin

There's no guarantee that the error handler worker thread
will run while the dispc clocks are on. Explicitly enable/disable
them.

Signed-off-by: Dima Zavin <dima@android.com>
---
 drivers/video/omap2/dss/dispc.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 62aa77c..2458248 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -3292,6 +3292,8 @@ static void dispc_error_worker(struct work_struct *work)
 	dispc.error_irqs = 0;
 	spin_unlock_irqrestore(&dispc.irq_lock, flags);
 
+	dispc_runtime_get();
+
 	if (errors & DISPC_IRQ_GFX_FIFO_UNDERFLOW) {
 		DSSERR("GFX_FIFO_UNDERFLOW, disabling GFX\n");
 		for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
@@ -3478,6 +3480,8 @@ static void dispc_error_worker(struct work_struct *work)
 	dispc.irq_error_mask |= errors;
 	_omap_dispc_set_irqs();
 	spin_unlock_irqrestore(&dispc.irq_lock, flags);
+
+	dispc_runtime_put();
 }
 
 int omap_dispc_wait_for_irq_timeout(u32 irqmask, unsigned long timeout)
-- 
1.7.3.1


^ permalink raw reply related

* [PATCH V7 0/5] ARM: EXYNOS4: Add support EXYNOS4 FIMD
From: JinGoo Han @ 2011-06-27 10:54 UTC (permalink / raw)
  To: Kukjin Kim, Paul Mundt, linux-samsung-soc@vger.kernel.org,
	"linux-fbdev@vger.kernel.org" <linux-f>
  Cc: ANAND KUMAR N, Sylwester Nawrocki, THOMAS P ABRAHAM,
	Marek Szyprowski, Kyungmin Park, In-Ki Dae, ARM Linux, Ben Dooks,
	JinGoo Han

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="windows-1254", Size: 1555 bytes --]

This patch series is based on the latest
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git

This was originally submitted by Jonghun Han <jonghun.han@samsung.com>
http://www.spinics.net/lists/arm-kernel/msg101781.html

This patch adds support FIMD(Fully Interactive Mobile Display) on Exynos4.
The 4th patch is update for s3c-fb and others are for platform data.

v2: change clock name of exynos4 FIMD: "fimd" -> "lcd"
     use 'has_clksel' variable in order to distinguish FIMD version
     add 'lcd_clk' that can be used for only lcd pixel clock
     add callback 'enable_clk()' to enable parent clock 'sclk_fimd'.
v3: remove the callback from the platform data structure
v4: move clk_enable(sfb->lcd_clk) under the if statement
v5: add clk_enable/disable(sfb->lcd_clk) to s3c_fb_runtime_suspend/resume().
v6: rename dev-fimd-24bpp.c to dev-fimd0.c
     add 'exynos4_fimd0_setup_clock()' to dev-fimd0.c to setup parent clock.
v7: remove parent clock setting from machine directory
     use ¡®gpio_request_one()¡¯ to simply the gpio setting step

o To Kukjin Kim
[PATCH V7 1/5] ARM: EXYNOS4: Change clock name for FIMD
[PATCH V7 2/5] ARM: EXYNOS4: Add FIMD resource definition
[PATCH V7 3/5] ARM: EXYNOS4: Add platform device and helper functions for FIMD
[PATCH V7 5/5] ARM: EXYNOS4: Add platform data for EXYNOS4 FIMD and LTE480WV platform-lcd

o To Paul Mundt
[PATCH V7 4/5] video: s3c-fb: Add support EXYNOS4

ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±ýöÝzÿâžØ^n‡r¡ö¦zË\x1aëh™¨è­Ú&£ûàz¿äz¹Þ—ú+€Ê+zf£¢·hšˆ§~†­†Ûiÿÿïêÿ‘êçz_è®\x0fæj:+v‰¨þ)ߣøm

^ permalink raw reply

* [PATCH V7 5/5] ARM: EXYNOS4: Add platform data for EXYNOS4 FIMD and LTE480WV platform-lcd
From: Jingoo Han @ 2011-06-27 10:50 UTC (permalink / raw)
  To: Kukjin Kim, Paul Mundt, linux-samsung-soc, linux-fbdev
  Cc: Anand Kumar N, Thomas Abraham, Sylwester Nawrocki,
	Marek Szyprowski, Kyungmin Park, Inki Dae, ARM Linux, Ben Dooks,
	Jonghun Han, Jingoo Han

From: Jonghun Han <jonghun.han@samsung.com>

This patch adds support EXYNOS4 FIMD0 and LTE480WV LCD pannel.

Signed-off-by: Jonghun Han <jonghun.han@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
 arch/arm/mach-exynos4/mach-smdkc210.c |   71 +++++++++++++++++++++++++++++++++
 arch/arm/mach-exynos4/mach-smdkv310.c |   71 +++++++++++++++++++++++++++++++++
 2 files changed, 142 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-exynos4/mach-smdkc210.c b/arch/arm/mach-exynos4/mach-smdkc210.c
index e645f7a..6528dec 100644
--- a/arch/arm/mach-exynos4/mach-smdkc210.c
+++ b/arch/arm/mach-exynos4/mach-smdkc210.c
@@ -9,7 +9,9 @@
 */
 
 #include <linux/serial_core.h>
+#include <linux/delay.h>
 #include <linux/gpio.h>
+#include <linux/lcd.h>
 #include <linux/mmc/host.h>
 #include <linux/platform_device.h>
 #include <linux/smsc911x.h>
@@ -19,16 +21,20 @@
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 
+#include <video/platform_lcd.h>
+
 #include <plat/regs-serial.h>
 #include <plat/regs-srom.h>
 #include <plat/exynos4.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
+#include <plat/fb.h>
 #include <plat/sdhci.h>
 #include <plat/iic.h>
 #include <plat/pd.h>
 
 #include <mach/map.h>
+#include <mach/regs-fb.h>
 
 /* Following are default values for UCON, ULCON and UFCON UART registers */
 #define SMDKC210_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
@@ -111,6 +117,67 @@ static struct s3c_sdhci_platdata smdkc210_hsmmc3_pdata __initdata = {
 	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
 };
 
+static void lcd_lte480wv_set_power(struct plat_lcd_data *pd,
+				   unsigned int power)
+{
+	if (power) {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+		gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_HIGH, "GPD0");
+		gpio_free(EXYNOS4_GPD0(1));
+#endif
+		/* fire nRESET on power up */
+		gpio_request(EXYNOS4_GPX0(6), "GPX0");
+
+		gpio_direction_output(EXYNOS4_GPX0(6), 1);
+		mdelay(100);
+
+		gpio_set_value(EXYNOS4_GPX0(6), 0);
+		mdelay(10);
+
+		gpio_set_value(EXYNOS4_GPX0(6), 1);
+		mdelay(10);
+
+		gpio_free(EXYNOS4_GPX0(6));
+	} else {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+		gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_LOW, "GPD0");
+		gpio_free(EXYNOS4_GPD0(1));
+#endif
+	}
+}
+
+static struct plat_lcd_data smdkc210_lcd_lte480wv_data = {
+	.set_power      = lcd_lte480wv_set_power,
+};
+
+static struct platform_device smdkc210_lcd_lte480wv = {
+	.name                   = "platform-lcd",
+	.dev.parent             = &s5p_device_fimd0.dev,
+	.dev.platform_data      = &smdkc210_lcd_lte480wv_data,
+};
+
+static struct s3c_fb_pd_win smdkc210_fb_win0 = {
+	.win_mode = {
+		.left_margin    = 13,
+		.right_margin   = 8,
+		.upper_margin   = 7,
+		.lower_margin   = 5,
+		.hsync_len      = 3,
+		.vsync_len      = 1,
+		.xres   = 800,
+		.yres   = 480,
+	},
+	.max_bpp        = 32,
+	.default_bpp    = 24,
+};
+
+static struct s3c_fb_platdata smdkc210_lcd0_pdata __initdata = {
+	.win[0]		= &smdkc210_fb_win0,
+	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+	.vidcon1	= VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+	.setup_gpio	= exynos4_fimd0_gpio_setup_24bpp,
+};
+
 static struct resource smdkc210_smsc911x_resources[] = {
 	[0] = {
 		.start	= EXYNOS4_PA_SROM_BANK(1),
@@ -165,6 +232,8 @@ static struct platform_device *smdkc210_devices[] __initdata = {
 	&exynos4_device_pd[PD_GPS],
 	&exynos4_device_sysmmu,
 	&samsung_asoc_dma,
+	&s5p_device_fimd0,
+	&smdkc210_lcd_lte480wv,
 	&smdkc210_smsc911x,
 };
 
@@ -210,6 +279,8 @@ static void __init smdkc210_machine_init(void)
 	s3c_sdhci2_set_platdata(&smdkc210_hsmmc2_pdata);
 	s3c_sdhci3_set_platdata(&smdkc210_hsmmc3_pdata);
 
+	s5p_fimd0_set_platdata(&smdkc210_lcd0_pdata);
+
 	platform_add_devices(smdkc210_devices, ARRAY_SIZE(smdkc210_devices));
 }
 
diff --git a/arch/arm/mach-exynos4/mach-smdkv310.c b/arch/arm/mach-exynos4/mach-smdkv310.c
index 1526764..a708276 100644
--- a/arch/arm/mach-exynos4/mach-smdkv310.c
+++ b/arch/arm/mach-exynos4/mach-smdkv310.c
@@ -9,7 +9,9 @@
 */
 
 #include <linux/serial_core.h>
+#include <linux/delay.h>
 #include <linux/gpio.h>
+#include <linux/lcd.h>
 #include <linux/mmc/host.h>
 #include <linux/platform_device.h>
 #include <linux/smsc911x.h>
@@ -20,17 +22,21 @@
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 
+#include <video/platform_lcd.h>
+
 #include <plat/regs-serial.h>
 #include <plat/regs-srom.h>
 #include <plat/exynos4.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
+#include <plat/fb.h>
 #include <plat/keypad.h>
 #include <plat/sdhci.h>
 #include <plat/iic.h>
 #include <plat/pd.h>
 
 #include <mach/map.h>
+#include <mach/regs-fb.h>
 
 /* Following are default values for UCON, ULCON and UFCON UART registers */
 #define SMDKV310_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
@@ -113,6 +119,67 @@ static struct s3c_sdhci_platdata smdkv310_hsmmc3_pdata __initdata = {
 	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
 };
 
+static void lcd_lte480wv_set_power(struct plat_lcd_data *pd,
+				   unsigned int power)
+{
+	if (power) {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+		gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_HIGH, "GPD0");
+		gpio_free(EXYNOS4_GPD0(1));
+#endif
+		/* fire nRESET on power up */
+		gpio_request(EXYNOS4_GPX0(6), "GPX0");
+
+		gpio_direction_output(EXYNOS4_GPX0(6), 1);
+		mdelay(100);
+
+		gpio_set_value(EXYNOS4_GPX0(6), 0);
+		mdelay(10);
+
+		gpio_set_value(EXYNOS4_GPX0(6), 1);
+		mdelay(10);
+
+		gpio_free(EXYNOS4_GPX0(6));
+	} else {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+		gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_LOW, "GPD0");
+		gpio_free(EXYNOS4_GPD0(1));
+#endif
+	}
+}
+
+static struct plat_lcd_data smdkv310_lcd_lte480wv_data = {
+	.set_power      = lcd_lte480wv_set_power,
+};
+
+static struct platform_device smdkv310_lcd_lte480wv = {
+	.name                   = "platform-lcd",
+	.dev.parent             = &s5p_device_fimd0.dev,
+	.dev.platform_data      = &smdkv310_lcd_lte480wv_data,
+};
+
+static struct s3c_fb_pd_win smdkv310_fb_win0 = {
+	.win_mode = {
+		.left_margin    = 13,
+		.right_margin   = 8,
+		.upper_margin   = 7,
+		.lower_margin   = 5,
+		.hsync_len      = 3,
+		.vsync_len      = 1,
+		.xres   = 800,
+		.yres   = 480,
+	},
+	.max_bpp        = 32,
+	.default_bpp    = 24,
+};
+
+static struct s3c_fb_platdata smdkv310_lcd0_pdata __initdata = {
+	.win[0]		= &smdkv310_fb_win0,
+	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+	.vidcon1	= VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+	.setup_gpio	= exynos4_fimd0_gpio_setup_24bpp,
+};
+
 static struct resource smdkv310_smsc911x_resources[] = {
 	[0] = {
 		.start	= EXYNOS4_PA_SROM_BANK(1),
@@ -187,6 +254,8 @@ static struct platform_device *smdkv310_devices[] __initdata = {
 	&exynos4_device_pd[PD_GPS],
 	&exynos4_device_sysmmu,
 	&samsung_asoc_dma,
+	&s5p_device_fimd0,
+	&smdkv310_lcd_lte480wv,
 	&smdkv310_smsc911x,
 };
 
@@ -232,6 +301,8 @@ static void __init smdkv310_machine_init(void)
 	s3c_sdhci2_set_platdata(&smdkv310_hsmmc2_pdata);
 	s3c_sdhci3_set_platdata(&smdkv310_hsmmc3_pdata);
 
+	s5p_fimd0_set_platdata(&smdkv310_lcd0_pdata);
+
 	samsung_keypad_set_platdata(&smdkv310_keypad_data);
 
 	platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices));
-- 
1.7.1


^ permalink raw reply related

* [PATCH V7 4/5] video: s3c-fb: Add support EXYNOS4 FIMD
From: Jingoo Han @ 2011-06-27 10:50 UTC (permalink / raw)
  To: Kukjin Kim, Paul Mundt, linux-samsung-soc, linux-fbdev,
	Jonghun Han
  Cc: Anand Kumar N, Thomas Abraham, Sylwester Nawrocki,
	Marek Szyprowski, Kyungmin Park, Inki Dae, ARM Linux, Ben Dooks,
	Jingoo Han

This patch adds struct s3c_fb_driverdata s3c_fb_data_exynos4 for EXYNOS4
and adds lcd clock gating support.

FIMD driver needs two clocks for FIMD IP and LCD pixel clock. Previously,
both clocks are provided by using bus clock such as HCLK. However, EXYNOS4
can not select HCLK for LCD pixel clock because the EXYNOS4 FIMD IP does not
have the CLKSEL bit of VIDCON0. So, FIMD driver should provide the lcd clock
using SCLK_FIMD as LCD pixel clock for EXYNOS4.

The driver selects enabling lcd clock according to has_clksel which means
the CLKSEL bit of VIDCON0. If there is has_clksel, the driver will not
enable the lcd clock using SCLK_FIMD because bus clock using HCLK is used
a LCD pixel clock.

Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
 drivers/video/Kconfig  |    2 +-
 drivers/video/s3c-fb.c |   88 +++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 85 insertions(+), 5 deletions(-)

diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 549b960..963b8b7 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2027,7 +2027,7 @@ config FB_TMIO_ACCELL
 
 config FB_S3C
 	tristate "Samsung S3C framebuffer support"
-	depends on FB && S3C_DEV_FB
+	depends on FB && (S3C_DEV_FB || S5P_DEV_FIMD0)
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 4aecf21..cb0d3ea 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -81,6 +81,7 @@ struct s3c_fb;
  * @palette: Address of palette memory, or 0 if none.
  * @has_prtcon: Set if has PRTCON register.
  * @has_shadowcon: Set if has SHADOWCON register.
+ * @has_clksel: Set if VIDCON0 register has CLKSEL bit.
  */
 struct s3c_fb_variant {
 	unsigned int	is_2443:1;
@@ -98,6 +99,7 @@ struct s3c_fb_variant {
 
 	unsigned int	has_prtcon:1;
 	unsigned int	has_shadowcon:1;
+	unsigned int	has_clksel:1;
 };
 
 /**
@@ -186,6 +188,7 @@ struct s3c_fb_vsync {
  * @dev: The device that we bound to, for printing, etc.
  * @regs_res: The resource we claimed for the IO registers.
  * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk.
+ * @lcd_clk: The clk (sclk) feeding pixclk.
  * @regs: The mapped hardware registers.
  * @variant: Variant information for this hardware.
  * @enabled: A bitmask of enabled hardware windows.
@@ -200,6 +203,7 @@ struct s3c_fb {
 	struct device		*dev;
 	struct resource		*regs_res;
 	struct clk		*bus_clk;
+	struct clk		*lcd_clk;
 	void __iomem		*regs;
 	struct s3c_fb_variant	 variant;
 
@@ -336,10 +340,15 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var,
  */
 static int s3c_fb_calc_pixclk(struct s3c_fb *sfb, unsigned int pixclk)
 {
-	unsigned long clk = clk_get_rate(sfb->bus_clk);
+	unsigned long clk;
 	unsigned long long tmp;
 	unsigned int result;
 
+	if (sfb->variant.has_clksel)
+		clk = clk_get_rate(sfb->bus_clk);
+	else
+		clk = clk_get_rate(sfb->lcd_clk);
+
 	tmp = (unsigned long long)clk;
 	tmp *= pixclk;
 
@@ -1354,13 +1363,24 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
 
 	clk_enable(sfb->bus_clk);
 
+	if (!sfb->variant.has_clksel) {
+		sfb->lcd_clk = clk_get(dev, "sclk_fimd");
+		if (IS_ERR(sfb->lcd_clk)) {
+			dev_err(dev, "failed to get lcd clock\n");
+			ret = PTR_ERR(sfb->lcd_clk);
+			goto err_bus_clk;
+		}
+
+		clk_enable(sfb->lcd_clk);
+	}
+
 	pm_runtime_enable(sfb->dev);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
 		dev_err(dev, "failed to find registers\n");
 		ret = -ENOENT;
-		goto err_clk;
+		goto err_lcd_clk;
 	}
 
 	sfb->regs_res = request_mem_region(res->start, resource_size(res),
@@ -1368,7 +1388,7 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
 	if (!sfb->regs_res) {
 		dev_err(dev, "failed to claim register region\n");
 		ret = -ENOENT;
-		goto err_clk;
+		goto err_lcd_clk;
 	}
 
 	sfb->regs = ioremap(res->start, resource_size(res));
@@ -1450,7 +1470,13 @@ err_ioremap:
 err_req_region:
 	release_mem_region(sfb->regs_res->start, resource_size(sfb->regs_res));
 
-err_clk:
+err_lcd_clk:
+	if (!sfb->variant.has_clksel) {
+		clk_disable(sfb->lcd_clk);
+		clk_put(sfb->lcd_clk);
+	}
+
+err_bus_clk:
 	clk_disable(sfb->bus_clk);
 	clk_put(sfb->bus_clk);
 
@@ -1481,6 +1507,11 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev)
 
 	iounmap(sfb->regs);
 
+	if (!sfb->variant.has_clksel) {
+		clk_disable(sfb->lcd_clk);
+		clk_put(sfb->lcd_clk);
+	}
+
 	clk_disable(sfb->bus_clk);
 	clk_put(sfb->bus_clk);
 
@@ -1510,6 +1541,9 @@ static int s3c_fb_suspend(struct device *dev)
 		s3c_fb_blank(FB_BLANK_POWERDOWN, win->fbinfo);
 	}
 
+	if (!sfb->variant.has_clksel)
+		clk_disable(sfb->lcd_clk);
+
 	clk_disable(sfb->bus_clk);
 	return 0;
 }
@@ -1524,6 +1558,9 @@ static int s3c_fb_resume(struct device *dev)
 
 	clk_enable(sfb->bus_clk);
 
+	if (!sfb->variant.has_clksel)
+		clk_enable(sfb->lcd_clk);
+
 	/* setup gpio and output polarity controls */
 	pd->setup_gpio();
 	writel(pd->vidcon1, sfb->regs + VIDCON1);
@@ -1569,6 +1606,9 @@ static int s3c_fb_runtime_suspend(struct device *dev)
 		s3c_fb_blank(FB_BLANK_POWERDOWN, win->fbinfo);
 	}
 
+	if (!sfb->variant.has_clksel)
+		clk_disable(sfb->lcd_clk);
+
 	clk_disable(sfb->bus_clk);
 	return 0;
 }
@@ -1583,6 +1623,9 @@ static int s3c_fb_runtime_resume(struct device *dev)
 
 	clk_enable(sfb->bus_clk);
 
+	if (!sfb->variant.has_clksel)
+		clk_enable(sfb->lcd_clk);
+
 	/* setup gpio and output polarity controls */
 	pd->setup_gpio();
 	writel(pd->vidcon1, sfb->regs + VIDCON1);
@@ -1755,6 +1798,7 @@ static struct s3c_fb_driverdata s3c_fb_data_64xx = {
 		},
 
 		.has_prtcon	= 1,
+		.has_clksel	= 1,
 	},
 	.win[0]	= &s3c_fb_data_64xx_wins[0],
 	.win[1]	= &s3c_fb_data_64xx_wins[1],
@@ -1785,6 +1829,7 @@ static struct s3c_fb_driverdata s3c_fb_data_s5pc100 = {
 		},
 
 		.has_prtcon	= 1,
+		.has_clksel	= 1,
 	},
 	.win[0]	= &s3c_fb_data_s5p_wins[0],
 	.win[1]	= &s3c_fb_data_s5p_wins[1],
@@ -1815,6 +1860,37 @@ static struct s3c_fb_driverdata s3c_fb_data_s5pv210 = {
 		},
 
 		.has_shadowcon	= 1,
+		.has_clksel	= 1,
+	},
+	.win[0]	= &s3c_fb_data_s5p_wins[0],
+	.win[1]	= &s3c_fb_data_s5p_wins[1],
+	.win[2]	= &s3c_fb_data_s5p_wins[2],
+	.win[3]	= &s3c_fb_data_s5p_wins[3],
+	.win[4]	= &s3c_fb_data_s5p_wins[4],
+};
+
+static struct s3c_fb_driverdata s3c_fb_data_exynos4 = {
+	.variant = {
+		.nr_windows	= 5,
+		.vidtcon	= VIDTCON0,
+		.wincon		= WINCON(0),
+		.winmap		= WINxMAP(0),
+		.keycon		= WKEYCON,
+		.osd		= VIDOSD_BASE,
+		.osd_stride	= 16,
+		.buf_start	= VIDW_BUF_START(0),
+		.buf_size	= VIDW_BUF_SIZE(0),
+		.buf_end	= VIDW_BUF_END(0),
+
+		.palette = {
+			[0] = 0x2400,
+			[1] = 0x2800,
+			[2] = 0x2c00,
+			[3] = 0x3000,
+			[4] = 0x3400,
+		},
+
+		.has_shadowcon	= 1,
 	},
 	.win[0]	= &s3c_fb_data_s5p_wins[0],
 	.win[1]	= &s3c_fb_data_s5p_wins[1],
@@ -1843,6 +1919,7 @@ static struct s3c_fb_driverdata s3c_fb_data_s3c2443 = {
 			[0] = 0x400,
 			[1] = 0x800,
 		},
+		.has_clksel	= 1,
 	},
 	.win[0] = &(struct s3c_fb_win_variant) {
 		.palette_sz	= 256,
@@ -1870,6 +1947,9 @@ static struct platform_device_id s3c_fb_driver_ids[] = {
 		.name		= "s5pv210-fb",
 		.driver_data	= (unsigned long)&s3c_fb_data_s5pv210,
 	}, {
+		.name		= "exynos4-fb",
+		.driver_data	= (unsigned long)&s3c_fb_data_exynos4,
+	}, {
 		.name		= "s3c2443-fb",
 		.driver_data	= (unsigned long)&s3c_fb_data_s3c2443,
 	},
-- 
1.7.1


^ permalink raw reply related


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