Linux Framebuffer Layer development
 help / color / mirror / Atom feed
* [PATCH 6/9] drivers/video: fsl-diu-fb: remove unused 'cursor_reset' variable
From: Timur Tabi @ 2012-10-16 22:33 UTC (permalink / raw)
  To: linux-fbdev

Probably left over from initial development in hardware cursor support
that never made it upstream.

Signed-off-by: Timur Tabi <timur@freescale.com>
---
 drivers/video/fsl-diu-fb.c |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index 6e32ba8..fa7f200 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -337,7 +337,6 @@ struct mfb_info {
 	int registered;
 	unsigned long pseudo_palette[16];
 	struct diu_ad *ad;
-	int cursor_reset;
 	unsigned char g_alpha;
 	unsigned int count;
 	int x_aoi_d;		/* aoi display x offset to physical screen */
@@ -982,7 +981,6 @@ static int fsl_diu_set_par(struct fb_info *info)
 	hw = data->diu_reg;
 
 	set_fix(info);
-	mfbi->cursor_reset = 1;
 
 	len = info->var.yres_virtual * info->fix.line_length;
 	/* Alloc & dealloc each time resolution/bpp change */
-- 
1.7.3.4



^ permalink raw reply related

* [PATCH 5/9] drivers/video: fsl-diu-fb: improve message displays
From: Timur Tabi @ 2012-10-16 22:33 UTC (permalink / raw)
  To: linux-fbdev

Add some debug and error messages that are useful during debugging.

Signed-off-by: Timur Tabi <timur@freescale.com>
---
 drivers/video/fsl-diu-fb.c |   34 +++++++++++++++++++++++++++++++++-
 1 files changed, 33 insertions(+), 1 deletions(-)

diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index f388c3a..6e32ba8 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -430,6 +430,22 @@ static struct mfb_info mfb_template[] = {
 	},
 };
 
+#ifdef DEBUG
+static void __attribute__ ((unused)) fsl_diu_dump(struct diu __iomem *hw)
+{
+	mb();
+	pr_debug("DIU: desc=%08x,%08x,%08x, gamma=%08x pallete=%08x "
+		 "cursor=%08x curs_pos=%08x diu_mode=%08x bgnd=%08x "
+		 "disp_size=%08x hsyn_para=%08x vsyn_para=%08x syn_pol=%08x "
+		 "thresholds=%08x int_mask=%08x plut=%08x\n",
+		 hw->desc[0], hw->desc[1], hw->desc[2], hw->gamma,
+		 hw->pallete, hw->cursor, hw->curs_pos, hw->diu_mode,
+		 hw->bgnd, hw->disp_size, hw->hsyn_para, hw->vsyn_para,
+		 hw->syn_pol, hw->thresholds, hw->int_mask, hw->plut);
+	rmb();
+}
+#endif
+
 /**
  * fsl_diu_name_to_port - convert a port name to a monitor port enum
  *
@@ -1108,6 +1124,12 @@ static int fsl_diu_ioctl(struct fb_info *info, unsigned int cmd,
 
 	if (!arg)
 		return -EINVAL;
+
+	dev_dbg(info->dev, "ioctl %08x (dir=%s%s type=%u nr=%u size=%u)\n", cmd,
+		_IOC_DIR(cmd) & _IOC_READ ? "R" : "",
+		_IOC_DIR(cmd) & _IOC_WRITE ? "W" : "",
+		_IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd));
+
 	switch (cmd) {
 	case MFB_SET_PIXFMT_OLD:
 		dev_warn(info->dev,
@@ -1754,6 +1776,9 @@ static int __init fsl_diu_init(void)
 	coherence_data_size = be32_to_cpup(prop) * 13;
 	coherence_data_size /= 8;
 
+	pr_debug("fsl-diu-fb: coherence data size is %zu bytes\n",
+		 coherence_data_size);
+
 	prop = of_get_property(np, "d-cache-line-size", NULL);
 	if (prop = NULL) {
 		pr_err("fsl-diu-fb: missing 'd-cache-line-size' property' "
@@ -1763,10 +1788,17 @@ static int __init fsl_diu_init(void)
 	}
 	d_cache_line_size = be32_to_cpup(prop);
 
+	pr_debug("fsl-diu-fb: cache lines size is %u bytes\n",
+		 d_cache_line_size);
+
 	of_node_put(np);
 	coherence_data = vmalloc(coherence_data_size);
-	if (!coherence_data)
+	if (!coherence_data) {
+		pr_err("fsl-diu-fb: could not allocate coherence data "
+		       "(size=%zu)\n", coherence_data_size);
 		return -ENOMEM;
+	}
+
 #endif
 
 	ret = platform_driver_register(&fsl_diu_driver);
-- 
1.7.3.4



^ permalink raw reply related

* [PATCH 4/9] drivers/video: fsl-diu-fb: streamline enabling of interrupts
From: Timur Tabi @ 2012-10-16 22:33 UTC (permalink / raw)
  To: linux-fbdev

Remove functions request_irq_local() and free_irq_local(), and merge
their code into the functions that handle opening and closing the
framebuffer.  We also improve the way that interrupts are enabled.

Also implement a work-around for broken U-Boots that leave the DIU
interrupts enabled.

Signed-off-by: Timur Tabi <timur@freescale.com>
---
 drivers/video/fsl-diu-fb.c |   73 ++++++++++++++++++++-----------------------
 1 files changed, 34 insertions(+), 39 deletions(-)

diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index 9c40547..f388c3a 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -1224,8 +1224,22 @@ static int fsl_diu_open(struct fb_info *info, int user)
 		res = fsl_diu_set_par(info);
 		if (res < 0)
 			mfbi->count--;
-		else
+		else {
+			struct fsl_diu_data *data = mfbi->parent;
+
+#ifdef CONFIG_NOT_COHERENT_CACHE
+			/*
+			 * Enable underrun detection and vertical sync
+			 * interrupts.
+			 */
+			clrbits32(&data->diu_reg->int_mask,
+				  INT_UNDRUN | INT_VSYNC);
+#else
+			/* Enable underrun detection */
+			clrbits32(&data->diu_reg->int_mask, INT_UNDRUN);
+#endif
 			fsl_diu_enable_panel(info);
+		}
 	}
 
 	spin_unlock(&diu_lock);
@@ -1241,8 +1255,13 @@ static int fsl_diu_release(struct fb_info *info, int user)
 
 	spin_lock(&diu_lock);
 	mfbi->count--;
-	if (mfbi->count = 0)
+	if (mfbi->count = 0) {
+		struct fsl_diu_data *data = mfbi->parent;
+
+		/* Disable interrupts */
+		out_be32(&data->diu_reg->int_mask, 0xffffffff);
 		fsl_diu_disable_panel(info);
+	}
 
 	spin_unlock(&diu_lock);
 	return res;
@@ -1380,7 +1399,7 @@ static void uninstall_fb(struct fb_info *info)
 static irqreturn_t fsl_diu_isr(int irq, void *dev_id)
 {
 	struct diu __iomem *hw = dev_id;
-	unsigned int status = in_be32(&hw->int_status);
+	uint32_t status = in_be32(&hw->int_status);
 
 	if (status) {
 		/* This is the workaround for underrun */
@@ -1405,40 +1424,6 @@ static irqreturn_t fsl_diu_isr(int irq, void *dev_id)
 	return IRQ_NONE;
 }
 
-static int request_irq_local(struct fsl_diu_data *data)
-{
-	struct diu __iomem *hw = data->diu_reg;
-	u32 ints;
-	int ret;
-
-	/* Read to clear the status */
-	in_be32(&hw->int_status);
-
-	ret = request_irq(data->irq, fsl_diu_isr, 0, "fsl-diu-fb", hw);
-	if (!ret) {
-		ints = INT_PARERR | INT_LS_BF_VS;
-#if !defined(CONFIG_NOT_COHERENT_CACHE)
-		ints |=	INT_VSYNC;
-#endif
-
-		/* Read to clear the status */
-		in_be32(&hw->int_status);
-		out_be32(&hw->int_mask, ints);
-	}
-
-	return ret;
-}
-
-static void free_irq_local(struct fsl_diu_data *data)
-{
-	struct diu __iomem *hw = data->diu_reg;
-
-	/* Disable all LCDC interrupt */
-	out_be32(&hw->int_mask, 0x1f);
-
-	free_irq(data->irq, NULL);
-}
-
 #ifdef CONFIG_PM
 /*
  * Power management hooks. Note that we won't be called from IRQ context,
@@ -1621,7 +1606,16 @@ static int __devinit fsl_diu_probe(struct platform_device *pdev)
 		}
 	}
 
-	if (request_irq_local(data)) {
+	/*
+	 * Older versions of U-Boot leave interrupts enabled, so disable
+	 * all of them and clear the status register.
+	 */
+	out_be32(&data->diu_reg->int_mask, 0xffffffff);
+	in_be32(&data->diu_reg->int_status);
+
+	ret = request_irq(data->irq, fsl_diu_isr, 0, "fsl-diu-fb",
+			  &data->diu_reg);
+	if (ret) {
 		dev_err(&pdev->dev, "could not claim irq\n");
 		goto error;
 	}
@@ -1656,7 +1650,8 @@ static int fsl_diu_remove(struct platform_device *pdev)
 
 	data = dev_get_drvdata(&pdev->dev);
 	disable_lcdc(&data->fsl_diu_info[0]);
-	free_irq_local(data);
+
+	free_irq(data->irq, &data->diu_reg);
 
 	for (i = 0; i < NUM_AOIS; i++)
 		uninstall_fb(&data->fsl_diu_info[i]);
-- 
1.7.3.4



^ permalink raw reply related

* [PATCH 3/9] drivers/video: fsl-diu-fb: add support for set_gamma ioctls
From: Timur Tabi @ 2012-10-16 22:33 UTC (permalink / raw)
  To: linux-fbdev

The MPC5121 BSP comes with a gamma_set utility that initializes the gamma
table via an ioctl.  Unfortunately, the ioctl number that utility uses
is defined improperly, but we can still support it.

Signed-off-by: Timur Tabi <timur@freescale.com>
---
 drivers/video/fsl-diu-fb.c |   17 +++++++++++++++++
 include/linux/fsl-diu-fb.h |    9 +++++++++
 2 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index 5b12e17..9c40547 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -1181,6 +1181,23 @@ static int fsl_diu_ioctl(struct fb_info *info, unsigned int cmd,
 			ad->ckmin_b = ck.blue_min;
 		}
 		break;
+#ifdef CONFIG_PPC_MPC512x
+	case MFB_SET_GAMMA: {
+		struct fsl_diu_data *data = mfbi->parent;
+
+		if (copy_from_user(data->gamma, buf, sizeof(data->gamma)))
+			return -EFAULT;
+		setbits32(&data->diu_reg->gamma, 0); /* Force table reload */
+		break;
+	}
+	case MFB_GET_GAMMA: {
+		struct fsl_diu_data *data = mfbi->parent;
+
+		if (copy_to_user(buf, data->gamma, sizeof(data->gamma)))
+			return -EFAULT;
+		break;
+	}
+#endif
 	default:
 		dev_err(info->dev, "unknown ioctl command (0x%08X)\n", cmd);
 		return -ENOIOCTLCMD;
diff --git a/include/linux/fsl-diu-fb.h b/include/linux/fsl-diu-fb.h
index 11c16a1..a1e8277 100644
--- a/include/linux/fsl-diu-fb.h
+++ b/include/linux/fsl-diu-fb.h
@@ -47,6 +47,15 @@ struct aoi_display_offset {
 #define MFB_GET_PIXFMT		_IOR('M', 8, __u32)
 
 /*
+ * The MPC5121 BSP comes with a gamma_set utility that initializes the
+ * gamma table.  Unfortunately, it uses bad values for the IOCTL commands,
+ * but there's nothing we can do about it now.  These ioctls are only
+ * supported on the MPC5121.
+ */
+#define MFB_SET_GAMMA		_IOW('M', 1, __u8)
+#define MFB_GET_GAMMA		_IOR('M', 1, __u8)
+
+/*
  * The original definitions of MFB_SET_PIXFMT and MFB_GET_PIXFMT used the
  * wrong value for 'size' field of the ioctl.  The current macros above use the
  * right size, but we still need to provide backwards compatibility, at least
-- 
1.7.3.4



^ permalink raw reply related

* [PATCH 2/9] drivers/video: fsl-diu-fb: simplify platforms that have only one port
From: Timur Tabi @ 2012-10-16 22:33 UTC (permalink / raw)
  To: linux-fbdev

Allow the platform code not to define a value for diu_ops.set_monitor_port.
This would be for platforms that only have one monitor port.
set_monitor_port() will never be called with an unsupported port anyway.

Signed-off-by: Timur Tabi <timur@freescale.com>
---
 drivers/video/fsl-diu-fb.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index ede9e55..5b12e17 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -792,7 +792,8 @@ static void update_lcdc(struct fb_info *info)
 
 	hw = data->diu_reg;
 
-	diu_ops.set_monitor_port(data->monitor_port);
+	if (diu_ops.set_monitor_port)
+		diu_ops.set_monitor_port(data->monitor_port);
 	gamma_table_base = data->gamma;
 
 	/* Prep for DIU init  - gamma table, cursor table */
-- 
1.7.3.4



^ permalink raw reply related

* [PATCH 1/9] MAINTAINERS: Make Timur Tabi the maintainer for the Freescale DIU driver
From: Timur Tabi @ 2012-10-16 22:33 UTC (permalink / raw)
  To: linux-fbdev

Timur has been cleaning up this driver, so just make it official.

Signed-off-by: Timur Tabi <timur@freescale.com>
---
 MAINTAINERS |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index fdc0119..1eeaaf5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2895,6 +2895,12 @@ F:	drivers/video/
 F:	include/video/
 F:	include/linux/fb.h
 
+FREESCALE DIU FRAMEBUFFER DRIVER
+M:	Timur Tabi <timur@freescale.com>
+L:	linux-fbdev@vger.kernel.org
+S:	Supported
+F:	drivers/video/fsl-diu-fb.*
+
 FREESCALE DMA DRIVER
 M:	Li Yang <leoli@freescale.com>
 M:	Zhang Wei <zw@zh-kernel.org>
-- 
1.7.3.4



^ permalink raw reply related

* [PATCH v3] video: Versatile Express DVI output driver
From: Pawel Moll @ 2012-10-16 16:30 UTC (permalink / raw)
  To: linux-arm-kernel

Versatile Express' DVI video output can be connected to one the three
sources - motherboard's CLCD controller or a video signal generated
by one of the daughterboards.

This driver configures the muxer FPGA so the output displays content
of one of the framebuffers in the system (0 by default, can be changed
by user writing to the "fb" sysfs attribute of the muxfpga device).

It will also set up the display formatter mode and keep it up
to date with mode changes requested by the user (eg. with fbset
tool).

Signed-off-by: Pawel Moll <pawel.moll@arm.com>
---
 drivers/video/Makefile       |    3 +
 drivers/video/vexpress-dvi.c |  220 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 223 insertions(+)
 create mode 100644 drivers/video/vexpress-dvi.c

Hi Florian,

This is pretty much the same stuff I posted a month ago...
Other relevant changes are on their way to 3.8.

Would you be so kind and have a look at it?  If the code looks fine,
would you prefer to merge it yourself, or should I push it through
arm-soc tree?

Thanks!

Pawel

diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 23e948e..2f4440d 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -167,3 +167,6 @@ obj-$(CONFIG_FB_VIRTUAL)          += vfb.o
 
 #video output switch sysfs driver
 obj-$(CONFIG_VIDEO_OUTPUT_CONTROL) += output.o
+
+# platform specific output drivers
+obj-$(CONFIG_VEXPRESS_CONFIG)	  += vexpress-dvi.o
diff --git a/drivers/video/vexpress-dvi.c b/drivers/video/vexpress-dvi.c
new file mode 100644
index 0000000..f087534
--- /dev/null
+++ b/drivers/video/vexpress-dvi.c
@@ -0,0 +1,220 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 ARM Limited
+ */
+
+#define pr_fmt(fmt) "vexpress-dvi: " fmt
+
+#include <linux/fb.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/vexpress.h>
+
+
+static struct vexpress_config_func *vexpress_dvimode_func;
+
+static struct {
+	u32 xres, yres, mode;
+} vexpress_dvi_dvimodes[] = {
+	{ 640, 480, 0 }, /* VGA */
+	{ 800, 600, 1 }, /* SVGA */
+	{ 1024, 768, 2 }, /* XGA */
+	{ 1280, 1024, 3 }, /* SXGA */
+	{ 1600, 1200, 4 }, /* UXGA */
+	{ 1920, 1080, 5 }, /* HD1080 */
+};
+
+static void vexpress_dvi_mode_set(struct fb_info *info, u32 xres, u32 yres)
+{
+	int err = -ENOENT;
+	int i;
+
+	if (!vexpress_dvimode_func)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(vexpress_dvi_dvimodes); i++) {
+		if (vexpress_dvi_dvimodes[i].xres == xres &&
+				vexpress_dvi_dvimodes[i].yres == yres) {
+			pr_debug("mode: %ux%u = %d\n", xres, yres,
+					vexpress_dvi_dvimodes[i].mode);
+			err = vexpress_config_write(vexpress_dvimode_func, 0,
+					vexpress_dvi_dvimodes[i].mode);
+			break;
+		}
+	}
+
+	if (err)
+		pr_warn("Failed to set %ux%u mode! (%d)\n", xres, yres, err);
+}
+
+
+static struct vexpress_config_func *vexpress_muxfpga_func;
+static int vexpress_dvi_fb = -1;
+
+static int vexpress_dvi_mux_set(struct fb_info *info)
+{
+	int err;
+	u32 site = vexpress_get_site_by_dev(info->device);
+
+	if (!vexpress_muxfpga_func)
+		return -ENXIO;
+
+	err = vexpress_config_write(vexpress_muxfpga_func, 0, site);
+	if (!err) {
+		pr_debug("Selected MUXFPGA input %d (fb%d)\n", site,
+				info->node);
+		vexpress_dvi_fb = info->node;
+		vexpress_dvi_mode_set(info, info->var.xres,
+				info->var.yres);
+	} else {
+		pr_warn("Failed to select MUXFPGA input %d (fb%d)! (%d)\n",
+				site, info->node, err);
+	}
+
+	return err;
+}
+
+static int vexpress_dvi_fb_select(int fb)
+{
+	int err;
+	struct fb_info *info;
+
+	/* fb0 is the default */
+	if (fb < 0)
+		fb = 0;
+
+	info = registered_fb[fb];
+	if (!info || !lock_fb_info(info))
+		return -ENODEV;
+
+	err = vexpress_dvi_mux_set(info);
+
+	unlock_fb_info(info);
+
+	return err;
+}
+
+static ssize_t vexpress_dvi_fb_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%d\n", vexpress_dvi_fb);
+}
+
+static ssize_t vexpress_dvi_fb_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	long value;
+	int err = kstrtol(buf, 0, &value);
+
+	if (!err)
+		err = vexpress_dvi_fb_select(value);
+
+	return err ? err : count;
+}
+
+DEVICE_ATTR(fb, S_IRUGO | S_IWUSR, vexpress_dvi_fb_show,
+		vexpress_dvi_fb_store);
+
+
+static int vexpress_dvi_fb_event_notify(struct notifier_block *self,
+			      unsigned long action, void *data)
+{
+	struct fb_event *event = data;
+	struct fb_info *info = event->info;
+	struct fb_videomode *mode = event->data;
+
+	switch (action) {
+	case FB_EVENT_FB_REGISTERED:
+		if (vexpress_dvi_fb < 0)
+			vexpress_dvi_mux_set(info);
+		break;
+	case FB_EVENT_MODE_CHANGE:
+	case FB_EVENT_MODE_CHANGE_ALL:
+		if (info->node == vexpress_dvi_fb)
+			vexpress_dvi_mode_set(info, mode->xres, mode->yres);
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block vexpress_dvi_fb_notifier = {
+	.notifier_call = vexpress_dvi_fb_event_notify,
+};
+static bool vexpress_dvi_fb_notifier_registered;
+
+
+enum vexpress_dvi_func { FUNC_MUXFPGA, FUNC_DVIMODE };
+
+static struct of_device_id vexpress_dvi_of_match[] = {
+	{
+		.compatible = "arm,vexpress-muxfpga",
+		.data = (void *)FUNC_MUXFPGA,
+	}, {
+		.compatible = "arm,vexpress-dvimode",
+		.data = (void *)FUNC_DVIMODE,
+	},
+	{}
+};
+
+static int vexpress_dvi_probe(struct platform_device *pdev)
+{
+	enum vexpress_dvi_func func;
+	const struct of_device_id *match =
+			of_match_device(vexpress_dvi_of_match, &pdev->dev);
+
+	if (match)
+		func = (enum vexpress_dvi_func)match->data;
+	else
+		func = pdev->id_entry->driver_data;
+
+	switch (func) {
+	case FUNC_MUXFPGA:
+		vexpress_muxfpga_func =
+				vexpress_config_func_get_by_dev(&pdev->dev);
+		device_create_file(&pdev->dev, &dev_attr_fb);
+		break;
+	case FUNC_DVIMODE:
+		vexpress_dvimode_func =
+				vexpress_config_func_get_by_dev(&pdev->dev);
+		break;
+	}
+
+	if (!vexpress_dvi_fb_notifier_registered) {
+		fb_register_client(&vexpress_dvi_fb_notifier);
+		vexpress_dvi_fb_notifier_registered = true;
+	}
+
+	vexpress_dvi_fb_select(vexpress_dvi_fb);
+
+	return 0;
+}
+
+static const struct platform_device_id vexpress_dvi_id_table[] = {
+	{ .name = "vexpress-muxfpga", .driver_data = FUNC_MUXFPGA, },
+	{ .name = "vexpress-dvimode", .driver_data = FUNC_DVIMODE, },
+	{}
+};
+
+static struct platform_driver vexpress_dvi_driver = {
+	.probe = vexpress_dvi_probe,
+	.driver = {
+		.name = "vexpress-dvi",
+		.of_match_table = vexpress_dvi_of_match,
+	},
+	.id_table = vexpress_dvi_id_table,
+};
+
+static int __init vexpress_dvi_init(void)
+{
+	return platform_driver_register(&vexpress_dvi_driver);
+}
+device_initcall(vexpress_dvi_init);
-- 
1.7.9.5



^ permalink raw reply related

* Re: [PATCH] OMAPDSS: Correct check for the callback pointer in dss_dsi_disable_pads()
From: Tomi Valkeinen @ 2012-10-16 13:31 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: Florian Tobias Schandinat, linux-fbdev, linux-omap, linux-kernel
In-Reply-To: <1350388281-20397-1-git-send-email-peter.ujfalusi@ti.com>

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

On 2012-10-16 14:51, Peter Ujfalusi wrote:
> Appear to be a copy-paste bug: the code was checking board_data->dsi_enable_pads
> while calling board_data->dsi_disable_pads.
> 
> 
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> ---
> 
> Hi Tomi,
> 
> not sure if this need to be included to 3.7

Thanks. Probably not needed for 3.7, as we never hit that bug with the
current kernel: if dsi_enable_pads is defined we also always define
dsi_disable_pads.

 Tomi



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

^ permalink raw reply

* [PATCH] OMAPDSS: Correct check for the callback pointer in dss_dsi_disable_pads()
From: Peter Ujfalusi @ 2012-10-16 11:51 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Florian Tobias Schandinat, linux-fbdev, linux-omap, linux-kernel

Appear to be a copy-paste bug: the code was checking board_data->dsi_enable_pads
while calling board_data->dsi_disable_pads.


Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---

Hi Tomi,

not sure if this need to be included to 3.7

Regards,
Peter

 drivers/video/omap2/dss/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index b2af72d..7afaf61 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -122,7 +122,7 @@ void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask)
 {
 	struct omap_dss_board_info *board_data = core.pdev->dev.platform_data;
 
-	if (!board_data->dsi_enable_pads)
+	if (!board_data->dsi_disable_pads)
 		return;
 
 	return board_data->dsi_disable_pads(dsi_id, lane_mask);
-- 
1.7.12.3


^ permalink raw reply related

* Re: [PATCH V5 1/2] video: exynos_dp: Add device tree support to DP driver
From: Sylwester Nawrocki @ 2012-10-16 11:07 UTC (permalink / raw)
  To: Jingoo Han
  Cc: 'Sylwester Nawrocki', 'Florian Tobias Schandinat',
	'Ajay Kumar', linux-samsung-soc, linux-fbdev,
	devicetree-discuss, 'Tomasz Figa',
	'Thomas Abraham'
In-Reply-To: <005a01cdab42$5a8ca390$0fa5eab0$%han@samsung.com>

On 10/16/2012 04:02 AM, Jingoo Han wrote:
> On Tuesday, October 16, 2012 6:14 AM Sylwester Nawrocki wrote
>> On 10/15/2012 10:14 AM, Jingoo Han wrote:
>>> On Saturday, October 13, 2012 6:44 AM Sylwester Nawrocki wrote
>>>>
>>>> On 10/12/2012 10:47 PM, Ajay Kumar wrote:
>>>>> This patch enables device tree based discovery support for DP driver.
>>>>> The driver is modified to handle platform data in both the cases:
>>>>> with DT and non-DT.
>>>>>
>>>>> Signed-off-by: Ajay Kumar<ajaykumar.rs@samsung.com>
>>>>> Acked-by: Jingoo Han<jg1.han@samsung.com>
>>>>> ---
>>>>>    drivers/video/exynos/exynos_dp_core.c |  161 ++++++++++++++++++++++++++++++---
>>>>>    drivers/video/exynos/exynos_dp_core.h |    2 +
>>>>>    2 files changed, 149 insertions(+), 14 deletions(-)
>> ...
>>>>> @@ -953,8 +1062,13 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev)
>>>>>    	struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
>>>>>    	struct exynos_dp_device *dp = platform_get_drvdata(pdev);
>>>>
>>>> This doesn't belong to your patch, but the above 2 lines could be written as:
>>>>
>>>>    	struct exynos_dp_device *dp = dev_get_drvdata(&pdev->dev);
>>>>
>>>> Same in functions exynos_dp_suspend() and exynos_dp_resume().
>>>
>>> No, above 2 lines cannot be reduced to 1 line, as you mentioned.
>>> This is because it makes build error.
>>
>> Sorry, my bad. It looks fine in case of exynos_dp_remove().
>>
>> But at exynos_dp_suspend/resume() there is something like:
>>
>>
>> static int exynos_dp_suspend(struct device *dev)
>> {
>> 	struct platform_device *pdev = to_platform_device(dev);
>> 	struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
>> 	struct exynos_dp_device *dp = platform_get_drvdata(pdev);
>>
>>
>> You need only pdata and dp there. I think that simpler form would
>> do as well:
>>
>> 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
>> 	struct exynos_dp_platdata *pdata = dev->platform_data;
> 
> OK, I see.
> I will accept your suggestion, because it is helpful to reduce
> lines. Then, I will send v8 patch, soon.

OK. I thought about it more as a candidate for a separate. But you seem
to have already sent new version, it's probably fine this way too.

--
Regards,
Sylwester

^ permalink raw reply

* [PATCH] video: s3c-fb: use dev_get_drvdata() instead of platform_get_drvdata()
From: Jingoo Han @ 2012-10-16  7:21 UTC (permalink / raw)
  To: linux-fbdev

Because there is no need to access to the platform device in
suspend/resume and runtime_suspend/resume, dev_get_drvdata()
can be used instead of platform_get_drvdata() to make the code
smaller.

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

diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 2ed7b63..95c6e30 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -1544,8 +1544,7 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev)
 #ifdef CONFIG_PM_SLEEP
 static int s3c_fb_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct s3c_fb *sfb = platform_get_drvdata(pdev);
+	struct s3c_fb *sfb = dev_get_drvdata(dev);
 	struct s3c_fb_win *win;
 	int win_no;
 
@@ -1572,8 +1571,7 @@ static int s3c_fb_suspend(struct device *dev)
 
 static int s3c_fb_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct s3c_fb *sfb = platform_get_drvdata(pdev);
+	struct s3c_fb *sfb = dev_get_drvdata(dev);
 	struct s3c_fb_platdata *pd = sfb->pdata;
 	struct s3c_fb_win *win;
 	int win_no;
@@ -1623,7 +1621,7 @@ static int s3c_fb_resume(struct device *dev)
 		if (!win)
 			continue;
 
-		dev_dbg(&pdev->dev, "resuming window %d\n", win_no);
+		dev_dbg(dev, "resuming window %d\n", win_no);
 		s3c_fb_set_par(win->fbinfo);
 	}
 
@@ -1636,8 +1634,7 @@ static int s3c_fb_resume(struct device *dev)
 #ifdef CONFIG_PM_RUNTIME
 static int s3c_fb_runtime_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct s3c_fb *sfb = platform_get_drvdata(pdev);
+	struct s3c_fb *sfb = dev_get_drvdata(dev);
 
 	if (!sfb->variant.has_clksel)
 		clk_disable_unprepare(sfb->lcd_clk);
@@ -1649,8 +1646,7 @@ static int s3c_fb_runtime_suspend(struct device *dev)
 
 static int s3c_fb_runtime_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct s3c_fb *sfb = platform_get_drvdata(pdev);
+	struct s3c_fb *sfb = dev_get_drvdata(dev);
 	struct s3c_fb_platdata *pd = sfb->pdata;
 
 	clk_prepare_enable(sfb->bus_clk);
-- 
1.7.1



^ permalink raw reply related

* [PATCH v2 2/2] da8xx-fb: cleanup LCDC configurations
From: Manjunathappa, Prakash @ 2012-10-16  5:05 UTC (permalink / raw)
  To: linux-fbdev

Configure below LCDC configurations to optimal values, also have an
option configure these optional parameters for platform.
1) AC bias configuration: Required only for passive panels
2) Dma_burst_size:
3) FIFO_DMA_DELAY:
4) FIFO threshold: Does not apply for da830 LCDC.

Patch is verified for 16bpp and 24bpp configurations on da830, da850 and
am335x EVMs.

Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
---
Since v1:
One of the patch in the series has changed, no change in this patch.

 arch/arm/mach-davinci/devices-da8xx.c |   22 +----------------
 drivers/video/da8xx-fb.c              |   43 +++++++++++++--------------------
 include/video/da8xx-fb.h              |   22 +----------------
 3 files changed, 19 insertions(+), 68 deletions(-)

diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index 783eab6..a61860a 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -524,29 +524,9 @@ void __init da8xx_register_mcasp(int id, struct snd_platform_data *pdata)
 	}
 }
 
-static const struct display_panel disp_panel = {
-	QVGA,
-	16,
-	16,
-	COLOR_ACTIVE,
-};
-
 static struct lcd_ctrl_config lcd_cfg = {
-	&disp_panel,
-	.ac_bias		= 255,
-	.ac_bias_intrpt		= 0,
-	.dma_burst_sz		= 16,
+	.panel_shade		= COLOR_ACTIVE,
 	.bpp			= 16,
-	.fdd			= 255,
-	.tft_alt_mode		= 0,
-	.stn_565_mode		= 0,
-	.mono_8bit_mode		= 0,
-	.invert_line_clock	= 1,
-	.invert_frm_clock	= 1,
-	.sync_edge		= 0,
-	.sync_ctrl		= 1,
-	.raster_order		= 0,
-	.fifo_th		= 6,
 };
 
 struct da8xx_lcdc_platform_data sharp_lcd035q3dg01_pdata = {
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 90cf33a..f0f21c8 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -226,7 +226,8 @@ static struct fb_videomode known_lcd_panels[] = {
 		.lower_margin   = 2,
 		.hsync_len      = 0,
 		.vsync_len      = 0,
-		.sync           = FB_SYNC_CLK_INVERT,
+		.sync           = FB_SYNC_CLK_INVERT |
+			FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
 	},
 	/* Sharp LK043T1DG01 */
 	[1] = {
@@ -240,7 +241,7 @@ static struct fb_videomode known_lcd_panels[] = {
 		.lower_margin   = 2,
 		.hsync_len      = 41,
 		.vsync_len      = 10,
-		.sync           = 0,
+		.sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
 		.flag           = 0,
 	},
 	[2] = {
@@ -255,7 +256,7 @@ static struct fb_videomode known_lcd_panels[] = {
 		.lower_margin   = 10,
 		.hsync_len      = 10,
 		.vsync_len      = 10,
-		.sync           = 0,
+		.sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
 		.flag           = 0,
 	},
 };
@@ -387,10 +388,9 @@ static int lcd_cfg_dma(int burst_size, int fifo_th)
 		reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_8);
 		break;
 	case 16:
+	default:
 		reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_16);
 		break;
-	default:
-		return -EINVAL;
 	}
 
 	reg |= (fifo_th << 8);
@@ -435,7 +435,8 @@ static void lcd_cfg_vertical_sync(int back_porch, int pulse_width,
 	lcdc_write(reg, LCD_RASTER_TIMING_1_REG);
 }
 
-static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
+static int lcd_cfg_display(const struct lcd_ctrl_config *cfg,
+		struct fb_videomode *panel)
 {
 	u32 reg;
 	u32 reg_int;
@@ -444,7 +445,7 @@ static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
 						LCD_MONO_8BIT_MODE |
 						LCD_MONOCHROME_MODE);
 
-	switch (cfg->p_disp_panel->panel_shade) {
+	switch (cfg->panel_shade) {
 	case MONOCHROME:
 		reg |= LCD_MONOCHROME_MODE;
 		if (cfg->mono_8bit_mode)
@@ -457,7 +458,9 @@ static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
 		break;
 
 	case COLOR_PASSIVE:
-		if (cfg->stn_565_mode)
+		/* AC bias applicable only for Pasive panels */
+		lcd_cfg_ac_bias(cfg->ac_bias, cfg->ac_bias_intrpt);
+		if (cfg->bpp = 12 && cfg->stn_565_mode)
 			reg |= LCD_STN_565_ENABLE;
 		break;
 
@@ -478,22 +481,19 @@ static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
 
 	reg = lcdc_read(LCD_RASTER_TIMING_2_REG);
 
-	if (cfg->sync_ctrl)
-		reg |= LCD_SYNC_CTRL;
-	else
-		reg &= ~LCD_SYNC_CTRL;
+	reg |= LCD_SYNC_CTRL;
 
 	if (cfg->sync_edge)
 		reg |= LCD_SYNC_EDGE;
 	else
 		reg &= ~LCD_SYNC_EDGE;
 
-	if (cfg->invert_line_clock)
+	if (panel->sync & FB_SYNC_HOR_HIGH_ACT)
 		reg |= LCD_INVERT_LINE_CLOCK;
 	else
 		reg &= ~LCD_INVERT_LINE_CLOCK;
 
-	if (cfg->invert_frm_clock)
+	if (panel->sync & FB_SYNC_VERT_HIGH_ACT)
 		reg |= LCD_INVERT_FRAME_CLOCK;
 	else
 		reg &= ~LCD_INVERT_FRAME_CLOCK;
@@ -738,9 +738,6 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
 	if (ret < 0)
 		return ret;
 
-	/* Configure the AC bias properties. */
-	lcd_cfg_ac_bias(cfg->ac_bias, cfg->ac_bias_intrpt);
-
 	/* Configure the vertical and horizontal sync properties. */
 	lcd_cfg_vertical_sync(panel->lower_margin, panel->vsync_len,
 			panel->upper_margin);
@@ -748,18 +745,12 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
 			panel->left_margin);
 
 	/* Configure for disply */
-	ret = lcd_cfg_display(cfg);
+	ret = lcd_cfg_display(cfg, panel);
 	if (ret < 0)
 		return ret;
 
-	if (QVGA != cfg->p_disp_panel->panel_type)
-		return -EINVAL;
+	bpp = cfg->bpp;
 
-	if (cfg->bpp <= cfg->p_disp_panel->max_bpp &&
-	    cfg->bpp >= cfg->p_disp_panel->min_bpp)
-		bpp = cfg->bpp;
-	else
-		bpp = cfg->p_disp_panel->max_bpp;
 	if (bpp = 12)
 		bpp = 16;
 	ret = lcd_cfg_frame_buffer(par, (unsigned int)panel->xres,
@@ -1381,7 +1372,7 @@ static int __devinit fb_probe(struct platform_device *device)
 	da8xx_fb_var.yres_virtual = lcdc_info->yres * LCD_NUM_BUFFERS;
 
 	da8xx_fb_var.grayscale -	    lcd_cfg->p_disp_panel->panel_shade = MONOCHROME ? 1 : 0;
+	    lcd_cfg->panel_shade = MONOCHROME ? 1 : 0;
 	da8xx_fb_var.bits_per_pixel = lcd_cfg->bpp;
 
 	da8xx_fb_var.hsync_len = lcdc_info->hsync_len;
diff --git a/include/video/da8xx-fb.h b/include/video/da8xx-fb.h
index 12e4e1d..f888259 100644
--- a/include/video/da8xx-fb.h
+++ b/include/video/da8xx-fb.h
@@ -12,10 +12,6 @@
 #ifndef DA8XX_FB_H
 #define DA8XX_FB_H
 
-enum panel_type {
-	QVGA = 0
-};
-
 enum panel_shade {
 	MONOCHROME = 0,
 	COLOR_ACTIVE,
@@ -27,13 +23,6 @@ enum raster_load_mode {
 	LOAD_PALETTE,
 };
 
-struct display_panel {
-	enum panel_type panel_type; /* QVGA */
-	int max_bpp;
-	int min_bpp;
-	enum panel_shade panel_shade;
-};
-
 struct da8xx_lcdc_platform_data {
 	const char manu_name[10];
 	void *controller_data;
@@ -42,7 +31,7 @@ struct da8xx_lcdc_platform_data {
 };
 
 struct lcd_ctrl_config {
-	const struct display_panel *p_disp_panel;
+	enum panel_shade panel_shade;
 
 	/* AC Bias Pin Frequency */
 	int ac_bias;
@@ -68,18 +57,9 @@ struct lcd_ctrl_config {
 	/* Mono 8-bit Mode: 1Ð-D7 or 0Ð-D3 */
 	unsigned char mono_8bit_mode;
 
-	/* Invert line clock */
-	unsigned char invert_line_clock;
-
-	/* Invert frame clock  */
-	unsigned char invert_frm_clock;
-
 	/* Horizontal and Vertical Sync Edge: 0=rising 1úlling */
 	unsigned char sync_edge;
 
-	/* Horizontal and Vertical Sync: Control: 0=ignore */
-	unsigned char sync_ctrl;
-
 	/* Raster Data Order Select: 1=Most-to-least 0=Least-to-most */
 	unsigned char raster_order;
 
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v2 1/2] da8xx-fb: adopt fb_videomode data for panel information
From: Manjunathappa, Prakash @ 2012-10-16  5:05 UTC (permalink / raw)
  To: linux-fbdev

Adopt fb_videomode data instead of defining driver private
structure to hold panel information. This is the way standard FB
drivers maintain the panel information.

Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
---
Since v1:
Do not move panel information out of driver, adopt only fb_videomode data.

 drivers/video/da8xx-fb.c |  130 +++++++++++++++++++++-------------------------
 include/video/da8xx-fb.h |    3 +
 2 files changed, 63 insertions(+), 70 deletions(-)

diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 65a11ef..90cf33a 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -213,62 +213,50 @@ static struct fb_fix_screeninfo da8xx_fb_fix __devinitdata = {
 	.accel = FB_ACCEL_NONE
 };
 
-struct da8xx_panel {
-	const char	name[25];	/* Full name <vendor>_<model> */
-	unsigned short	width;
-	unsigned short	height;
-	int		hfp;		/* Horizontal front porch */
-	int		hbp;		/* Horizontal back porch */
-	int		hsw;		/* Horizontal Sync Pulse Width */
-	int		vfp;		/* Vertical front porch */
-	int		vbp;		/* Vertical back porch */
-	int		vsw;		/* Vertical Sync Pulse Width */
-	unsigned int	pxl_clk;	/* Pixel clock */
-	unsigned char	invert_pxl_clk;	/* Invert Pixel clock */
-};
-
-static struct da8xx_panel known_lcd_panels[] = {
+static struct fb_videomode known_lcd_panels[] = {
 	/* Sharp LCD035Q3DG01 */
 	[0] = {
-		.name = "Sharp_LCD035Q3DG01",
-		.width = 320,
-		.height = 240,
-		.hfp = 8,
-		.hbp = 6,
-		.hsw = 0,
-		.vfp = 2,
-		.vbp = 2,
-		.vsw = 0,
-		.pxl_clk = 4608000,
-		.invert_pxl_clk = 1,
+		.name           = "Sharp_LCD035Q3DG01",
+		.xres           = 320,
+		.yres           = 240,
+		.pixclock       = 4608000,
+		.left_margin    = 6,
+		.right_margin   = 8,
+		.upper_margin   = 2,
+		.lower_margin   = 2,
+		.hsync_len      = 0,
+		.vsync_len      = 0,
+		.sync           = FB_SYNC_CLK_INVERT,
 	},
 	/* Sharp LK043T1DG01 */
 	[1] = {
-		.name = "Sharp_LK043T1DG01",
-		.width = 480,
-		.height = 272,
-		.hfp = 2,
-		.hbp = 2,
-		.hsw = 41,
-		.vfp = 2,
-		.vbp = 2,
-		.vsw = 10,
-		.pxl_clk = 7833600,
-		.invert_pxl_clk = 0,
+		.name           = "Sharp_LK043T1DG01",
+		.xres           = 480,
+		.yres           = 272,
+		.pixclock       = 7833600,
+		.left_margin    = 2,
+		.right_margin   = 2,
+		.upper_margin   = 2,
+		.lower_margin   = 2,
+		.hsync_len      = 41,
+		.vsync_len      = 10,
+		.sync           = 0,
+		.flag           = 0,
 	},
 	[2] = {
 		/* Hitachi SP10Q010 */
-		.name = "SP10Q010",
-		.width = 320,
-		.height = 240,
-		.hfp = 10,
-		.hbp = 10,
-		.hsw = 10,
-		.vfp = 10,
-		.vbp = 10,
-		.vsw = 10,
-		.pxl_clk = 7833600,
-		.invert_pxl_clk = 0,
+		.name           = "SP10Q010",
+		.xres           = 320,
+		.yres           = 240,
+		.pixclock       = 7833600,
+		.left_margin    = 10,
+		.right_margin   = 10,
+		.upper_margin   = 10,
+		.lower_margin   = 10,
+		.hsync_len      = 10,
+		.vsync_len      = 10,
+		.sync           = 0,
+		.flag           = 0,
 	},
 };
 
@@ -728,7 +716,7 @@ static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
 }
 
 static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
-		struct da8xx_panel *panel)
+		struct fb_videomode *panel)
 {
 	u32 bpp;
 	int ret = 0;
@@ -738,7 +726,7 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
 	/* Calculate the divider */
 	lcd_calc_clk_divider(par);
 
-	if (panel->invert_pxl_clk)
+	if (panel->sync & FB_SYNC_CLK_INVERT)
 		lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) |
 			LCD_INVERT_PIXEL_CLOCK), LCD_RASTER_TIMING_2_REG);
 	else
@@ -754,8 +742,10 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
 	lcd_cfg_ac_bias(cfg->ac_bias, cfg->ac_bias_intrpt);
 
 	/* Configure the vertical and horizontal sync properties. */
-	lcd_cfg_vertical_sync(panel->vbp, panel->vsw, panel->vfp);
-	lcd_cfg_horizontal_sync(panel->hbp, panel->hsw, panel->hfp);
+	lcd_cfg_vertical_sync(panel->lower_margin, panel->vsync_len,
+			panel->upper_margin);
+	lcd_cfg_horizontal_sync(panel->right_margin, panel->hsync_len,
+			panel->left_margin);
 
 	/* Configure for disply */
 	ret = lcd_cfg_display(cfg);
@@ -772,8 +762,8 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
 		bpp = cfg->p_disp_panel->max_bpp;
 	if (bpp = 12)
 		bpp = 16;
-	ret = lcd_cfg_frame_buffer(par, (unsigned int)panel->width,
-				(unsigned int)panel->height, bpp,
+	ret = lcd_cfg_frame_buffer(par, (unsigned int)panel->xres,
+				(unsigned int)panel->yres, bpp,
 				cfg->raster_order);
 	if (ret < 0)
 		return ret;
@@ -1235,7 +1225,7 @@ static int __devinit fb_probe(struct platform_device *device)
 	struct da8xx_lcdc_platform_data *fb_pdata  						device->dev.platform_data;
 	struct lcd_ctrl_config *lcd_cfg;
-	struct da8xx_panel *lcdc_info;
+	struct fb_videomode *lcdc_info;
 	struct fb_info *da8xx_fb_info;
 	struct clk *fb_clk = NULL;
 	struct da8xx_fb_par *par;
@@ -1323,7 +1313,7 @@ static int __devinit fb_probe(struct platform_device *device)
 #ifdef CONFIG_CPU_FREQ
 	par->lcd_fck_rate = clk_get_rate(fb_clk);
 #endif
-	par->pxl_clk = lcdc_info->pxl_clk;
+	par->pxl_clk = lcdc_info->pixclock;
 	if (fb_pdata->panel_power_ctrl) {
 		par->panel_power_ctrl = fb_pdata->panel_power_ctrl;
 		par->panel_power_ctrl(1);
@@ -1336,8 +1326,8 @@ static int __devinit fb_probe(struct platform_device *device)
 	}
 
 	/* allocate frame buffer */
-	par->vram_size = lcdc_info->width * lcdc_info->height * lcd_cfg->bpp;
-	ulcm = lcm((lcdc_info->width * lcd_cfg->bpp)/8, PAGE_SIZE);
+	par->vram_size = lcdc_info->xres * lcdc_info->yres * lcd_cfg->bpp;
+	ulcm = lcm((lcdc_info->xres * lcd_cfg->bpp)/8, PAGE_SIZE);
 	par->vram_size = roundup(par->vram_size/8, ulcm);
 	par->vram_size = par->vram_size * LCD_NUM_BUFFERS;
 
@@ -1355,10 +1345,10 @@ static int __devinit fb_probe(struct platform_device *device)
 	da8xx_fb_info->screen_base = (char __iomem *) par->vram_virt;
 	da8xx_fb_fix.smem_start    = par->vram_phys;
 	da8xx_fb_fix.smem_len      = par->vram_size;
-	da8xx_fb_fix.line_length   = (lcdc_info->width * lcd_cfg->bpp) / 8;
+	da8xx_fb_fix.line_length   = (lcdc_info->xres * lcd_cfg->bpp) / 8;
 
 	par->dma_start = par->vram_phys;
-	par->dma_end   = par->dma_start + lcdc_info->height *
+	par->dma_end   = par->dma_start + lcdc_info->yres *
 		da8xx_fb_fix.line_length - 1;
 
 	/* allocate palette buffer */
@@ -1384,22 +1374,22 @@ static int __devinit fb_probe(struct platform_device *device)
 	/* Initialize par */
 	da8xx_fb_info->var.bits_per_pixel = lcd_cfg->bpp;
 
-	da8xx_fb_var.xres = lcdc_info->width;
-	da8xx_fb_var.xres_virtual = lcdc_info->width;
+	da8xx_fb_var.xres = lcdc_info->xres;
+	da8xx_fb_var.xres_virtual = lcdc_info->xres;
 
-	da8xx_fb_var.yres         = lcdc_info->height;
-	da8xx_fb_var.yres_virtual = lcdc_info->height * LCD_NUM_BUFFERS;
+	da8xx_fb_var.yres         = lcdc_info->yres;
+	da8xx_fb_var.yres_virtual = lcdc_info->yres * LCD_NUM_BUFFERS;
 
 	da8xx_fb_var.grayscale  	    lcd_cfg->p_disp_panel->panel_shade = MONOCHROME ? 1 : 0;
 	da8xx_fb_var.bits_per_pixel = lcd_cfg->bpp;
 
-	da8xx_fb_var.hsync_len = lcdc_info->hsw;
-	da8xx_fb_var.vsync_len = lcdc_info->vsw;
-	da8xx_fb_var.right_margin = lcdc_info->hfp;
-	da8xx_fb_var.left_margin  = lcdc_info->hbp;
-	da8xx_fb_var.lower_margin = lcdc_info->vfp;
-	da8xx_fb_var.upper_margin = lcdc_info->vbp;
+	da8xx_fb_var.hsync_len = lcdc_info->hsync_len;
+	da8xx_fb_var.vsync_len = lcdc_info->vsync_len;
+	da8xx_fb_var.right_margin = lcdc_info->right_margin;
+	da8xx_fb_var.left_margin  = lcdc_info->left_margin;
+	da8xx_fb_var.lower_margin = lcdc_info->lower_margin;
+	da8xx_fb_var.upper_margin = lcdc_info->upper_margin;
 	da8xx_fb_var.pixclock = da8xxfb_pixel_clk_period(par);
 
 	/* Initialize fbinfo */
diff --git a/include/video/da8xx-fb.h b/include/video/da8xx-fb.h
index 5a0e4f9..12e4e1d 100644
--- a/include/video/da8xx-fb.h
+++ b/include/video/da8xx-fb.h
@@ -103,5 +103,8 @@ struct lcd_sync_arg {
 #define FBIPUT_HSYNC		_IOW('F', 9, int)
 #define FBIPUT_VSYNC		_IOW('F', 10, int)
 
+/* Proprietary FB_SYNC_ flags */
+#define FB_SYNC_CLK_INVERT 0x40000000
+
 #endif  /* ifndef DA8XX_FB_H */
 
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v2 0/2] da8xx-fb: LCDC driver cleanup
From: Manjunathappa, Prakash @ 2012-10-16  5:05 UTC (permalink / raw)
  To: linux-fbdev

This patch series clean up driver as it is necessary for DT migration.

Manjunathappa, Prakash (2):
  da8xx-fb: adopt fb_videomode data for panel information
  da8xx-fb: cleanup LCDC configurations

 arch/arm/mach-davinci/devices-da8xx.c |   22 +----
 drivers/video/da8xx-fb.c              |  167 +++++++++++++++------------------
 include/video/da8xx-fb.h              |   25 +----
 3 files changed, 79 insertions(+), 135 deletions(-)


^ permalink raw reply

* [PATCH V8 2/2] video: exynos_dp: device tree documentation
From: Jingoo Han @ 2012-10-16  2:17 UTC (permalink / raw)
  To: 'Florian Tobias Schandinat'
  Cc: linux-fbdev, linux-samsung-soc, devicetree-discuss,
	'Ajay Kumar', 'Sylwester Nawrocki',
	'Tomasz Figa', 'Thomas Abraham',
	'Jingoo Han'

From: Ajay Kumar <ajaykumar.rs@samsung.com>

Add documentation for the DT bindings in exynos display port driver.

Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
No changes since v7:

 .../devicetree/bindings/video/exynos_dp.txt        |   80 ++++++++++++++++++++
 1 files changed, 80 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/video/exynos_dp.txt

diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt
new file mode 100644
index 0000000..7cc7d9f
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
@@ -0,0 +1,80 @@
+The Exynos display port interface should be configured based on
+the type of panel connected to it.
+
+We use two nodes:
+	-display-port-controller node
+	-dptx-phy node(defined inside display-port-controller node)
+
+For the DP-PHY initialization, we use the dptx-phy node.
+Required properties for dptx-phy:
+	-reg:
+		Base address of DP PHY register.
+	-samsung,enable-mask:
+		The bit-mask used to enable/disable DP PHY.
+
+For the Panel initialization, we read data from display-port-controller node.
+Required properties for display-port-controller:
+	-compatible:
+		should be "samsung,exynos5-dp".
+	-reg:
+		physical base address of the controller and length
+		of memory mapped region.
+	-interrupts:
+		interrupt combiner values.
+	-interrupt-parent:
+		phandle to Interrupt combiner node.
+	-samsung,color-space:
+		input video data format.
+			COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
+	-samsung,dynamic-range:
+		dynamic range for input video data.
+			VESA = 0, CEA = 1
+	-samsung,ycbcr-coeff:
+		YCbCr co-efficients for input video.
+			COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
+	-samsung,color-depth:
+		number of bits per colour component.
+			COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
+	-samsung,link-rate:
+		link rate supported by the panel.
+			LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A
+	-samsung,lane-count:
+		number of lanes supported by the panel.
+			LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
+
+Optional properties for display-port-controller:
+	-interlaced:
+		interlace scan mode.
+			Progressive if defined, Interlaced if not defined
+	-vsync-active-high:
+		VSYNC polarity configuration.
+			High if defined, Low if not defined
+	-hsync-active-high:
+		HSYNC polarity configuration.
+			High if defined, Low if not defined
+
+Example:
+
+SOC specific portion:
+	display-port-controller {
+		compatible = "samsung,exynos5-dp";
+		reg = <0x145b0000 0x10000>;
+		interrupts = <10 3>;
+		interrupt-parent = <&combiner>;
+
+		dptx-phy {
+			reg = <0x10040720>;
+			samsung,enable-mask = <1>;
+		};
+
+        };
+
+Board Specific portion:
+	display-port-controller {
+		samsung,color-space = <0>;
+		samsung,dynamic-range = <0>;
+		samsung,ycbcr-coeff = <0>;
+		samsung,color-depth = <1>;
+		samsung,link-rate = <0x0a>;
+		samsung,lane-count = <4>;
+	};
-- 
1.7.1



^ permalink raw reply related

* [PATCH V8 1/2] video: exynos_dp: Add device tree support to DP driver
From: Jingoo Han @ 2012-10-16  2:16 UTC (permalink / raw)
  To: 'Florian Tobias Schandinat'
  Cc: linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA, 'Jingoo Han',
	'Ajay Kumar', 'Sylwester Nawrocki',
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

From: Ajay Kumar <ajaykumar.rs@samsung.com>

This patch enables device tree based discovery support for DP driver.
The driver is modified to handle platform data in both the cases:
with DT and non-DT.

Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
This patch is tested with Exynos5250.

Changes since v7:
- Replace platform_get_drvdata() with dev_get_drvdata() in suspend/resume

 drivers/video/exynos/exynos_dp_core.c |  216 ++++++++++++++++++++++++++++++---
 drivers/video/exynos/exynos_dp_core.h |    2 +
 2 files changed, 198 insertions(+), 20 deletions(-)

diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index d55470e..9a9ecc1 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -18,6 +18,7 @@
 #include <linux/io.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/of.h>
 
 #include <video/exynos_dp.h>
 
@@ -856,6 +857,145 @@ static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
 	return IRQ_HANDLED;
 }
 
+#ifdef CONFIG_OF
+static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
+{
+	struct device_node *dp_node = dev->of_node;
+	struct exynos_dp_platdata *pd;
+	struct video_info *dp_video_config;
+
+	pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
+	if (!pd) {
+		dev_err(dev, "memory allocation for pdata failed\n");
+		return ERR_PTR(-ENOMEM);
+	}
+	dp_video_config = devm_kzalloc(dev,
+				sizeof(*dp_video_config), GFP_KERNEL);
+
+	if (!dp_video_config) {
+		dev_err(dev, "memory allocation for video config failed\n");
+		return ERR_PTR(-ENOMEM);
+	}
+	pd->video_info = dp_video_config;
+
+	dp_video_config->h_sync_polarity +		of_property_read_bool(dp_node, "hsync-active-high");
+
+	dp_video_config->v_sync_polarity +		of_property_read_bool(dp_node, "vsync-active-high");
+
+	dp_video_config->interlaced +		of_property_read_bool(dp_node, "interlaced");
+
+	if (of_property_read_u32(dp_node, "samsung,color-space",
+				&dp_video_config->color_space)) {
+		dev_err(dev, "failed to get color-space\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (of_property_read_u32(dp_node, "samsung,dynamic-range",
+				&dp_video_config->dynamic_range)) {
+		dev_err(dev, "failed to get dynamic-range\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (of_property_read_u32(dp_node, "samsung,ycbcr-coeff",
+				&dp_video_config->ycbcr_coeff)) {
+		dev_err(dev, "failed to get ycbcr-coeff\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (of_property_read_u32(dp_node, "samsung,color-depth",
+				&dp_video_config->color_depth)) {
+		dev_err(dev, "failed to get color-depth\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (of_property_read_u32(dp_node, "samsung,link-rate",
+				&dp_video_config->link_rate)) {
+		dev_err(dev, "failed to get link-rate\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (of_property_read_u32(dp_node, "samsung,lane-count",
+				&dp_video_config->lane_count)) {
+		dev_err(dev, "failed to get lane-count\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	return pd;
+}
+
+static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
+{
+	struct device_node *dp_phy_node;
+	u32 phy_base;
+
+	dp_phy_node = of_find_node_by_name(dp->dev->of_node, "dptx-phy");
+	if (!dp_phy_node) {
+		dev_err(dp->dev, "could not find dptx-phy node\n");
+		return -ENODEV;
+	}
+
+	if (of_property_read_u32(dp_phy_node, "reg", &phy_base)) {
+		dev_err(dp->dev, "faild to get reg for dptx-phy\n");
+		return -EINVAL;
+	}
+
+	if (of_property_read_u32(dp_phy_node, "samsung,enable-mask",
+				&dp->enable_mask)) {
+		dev_err(dp->dev, "faild to get enable-mask for dptx-phy\n");
+		return -EINVAL;
+	}
+
+	dp->phy_addr = ioremap(phy_base, SZ_4);
+	if (!dp->phy_addr) {
+		dev_err(dp->dev, "failed to ioremap dp-phy\n");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void exynos_dp_phy_init(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = __raw_readl(dp->phy_addr);
+	reg |= dp->enable_mask;
+	__raw_writel(reg, dp->phy_addr);
+}
+
+static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = __raw_readl(dp->phy_addr);
+	reg &= ~(dp->enable_mask);
+	__raw_writel(reg, dp->phy_addr);
+}
+#else
+static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
+{
+	return NULL;
+}
+
+static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
+{
+	return -EINVAL;
+}
+
+static void exynos_dp_phy_init(struct exynos_dp_device *dp)
+{
+	return;
+}
+
+static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
+{
+	return;
+}
+#endif /* CONFIG_OF */
+
 static int __devinit exynos_dp_probe(struct platform_device *pdev)
 {
 	struct resource *res;
@@ -864,12 +1004,6 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
 
 	int ret = 0;
 
-	pdata = pdev->dev.platform_data;
-	if (!pdata) {
-		dev_err(&pdev->dev, "no platform data\n");
-		return -EINVAL;
-	}
-
 	dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
 				GFP_KERNEL);
 	if (!dp) {
@@ -879,6 +1013,22 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
 
 	dp->dev = &pdev->dev;
 
+	if (pdev->dev.of_node) {
+		pdata = exynos_dp_dt_parse_pdata(&pdev->dev);
+		if (IS_ERR(pdata))
+			return PTR_ERR(pdata);
+
+		ret = exynos_dp_dt_parse_phydata(dp);
+		if (ret)
+			return ret;
+	} else {
+		pdata = pdev->dev.platform_data;
+		if (!pdata) {
+			dev_err(&pdev->dev, "no platform data\n");
+			return -EINVAL;
+		}
+	}
+
 	dp->clock = devm_clk_get(&pdev->dev, "dp");
 	if (IS_ERR(dp->clock)) {
 		dev_err(&pdev->dev, "failed to get clock\n");
@@ -909,8 +1059,14 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
 	}
 
 	dp->video_info = pdata->video_info;
-	if (pdata->phy_init)
-		pdata->phy_init();
+
+	if (pdev->dev.of_node) {
+		if (dp->phy_addr)
+			exynos_dp_phy_init(dp);
+	} else {
+		if (pdata->phy_init)
+			pdata->phy_init();
+	}
 
 	exynos_dp_init_dp(dp);
 
@@ -953,8 +1109,13 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev)
 	struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
 	struct exynos_dp_device *dp = platform_get_drvdata(pdev);
 
-	if (pdata && pdata->phy_exit)
-		pdata->phy_exit();
+	if (pdev->dev.of_node) {
+		if (dp->phy_addr)
+			exynos_dp_phy_exit(dp);
+	} else {
+		if (pdata->phy_exit)
+			pdata->phy_exit();
+	}
 
 	clk_disable_unprepare(dp->clock);
 
@@ -964,12 +1125,16 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev)
 #ifdef CONFIG_PM_SLEEP
 static int exynos_dp_suspend(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
-	struct exynos_dp_device *dp = platform_get_drvdata(pdev);
+	struct exynos_dp_platdata *pdata = dev->platform_data;
+	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
-	if (pdata && pdata->phy_exit)
-		pdata->phy_exit();
+	if (dev->of_node) {
+		if (dp->phy_addr)
+			exynos_dp_phy_exit(dp);
+	} else {
+		if (pdata->phy_exit)
+			pdata->phy_exit();
+	}
 
 	clk_disable_unprepare(dp->clock);
 
@@ -978,12 +1143,16 @@ static int exynos_dp_suspend(struct device *dev)
 
 static int exynos_dp_resume(struct device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
-	struct exynos_dp_device *dp = platform_get_drvdata(pdev);
+	struct exynos_dp_platdata *pdata = dev->platform_data;
+	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
-	if (pdata && pdata->phy_init)
-		pdata->phy_init();
+	if (dev->of_node) {
+		if (dp->phy_addr)
+			exynos_dp_phy_init(dp);
+	} else {
+		if (pdata->phy_init)
+			pdata->phy_init();
+	}
 
 	clk_prepare_enable(dp->clock);
 
@@ -1013,6 +1182,12 @@ static const struct dev_pm_ops exynos_dp_pm_ops = {
 	SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume)
 };
 
+static const struct of_device_id exynos_dp_match[] = {
+	{ .compatible = "samsung,exynos5-dp" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, exynos_dp_match);
+
 static struct platform_driver exynos_dp_driver = {
 	.probe		= exynos_dp_probe,
 	.remove		= __devexit_p(exynos_dp_remove),
@@ -1020,6 +1195,7 @@ static struct platform_driver exynos_dp_driver = {
 		.name	= "exynos-dp",
 		.owner	= THIS_MODULE,
 		.pm	= &exynos_dp_pm_ops,
+		.of_match_table = of_match_ptr(exynos_dp_match),
 	},
 };
 
diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h
index 57b8a65..6dbeeb2 100644
--- a/drivers/video/exynos/exynos_dp_core.h
+++ b/drivers/video/exynos/exynos_dp_core.h
@@ -29,6 +29,8 @@ struct exynos_dp_device {
 	struct clk		*clock;
 	unsigned int		irq;
 	void __iomem		*reg_base;
+	void __iomem		*phy_addr;
+	unsigned int		enable_mask;
 
 	struct video_info	*video_info;
 	struct link_train	link_train;
-- 
1.7.1



^ permalink raw reply related

* Re: [PATCH V5 1/2] video: exynos_dp: Add device tree support to DP driver
From: Jingoo Han @ 2012-10-16  2:02 UTC (permalink / raw)
  To: 'Sylwester Nawrocki'
  Cc: 'Florian Tobias Schandinat', 'Ajay Kumar',
	linux-samsung-soc, linux-fbdev, devicetree-discuss,
	'Tomasz Figa', 'Thomas Abraham',
	'Jingoo Han'
In-Reply-To: <507C7C9E.1030503@gmail.com>

On Tuesday, October 16, 2012 6:14 AM Sylwester Nawrocki wrote
> 
> On 10/15/2012 10:14 AM, Jingoo Han wrote:
> > On Saturday, October 13, 2012 6:44 AM Sylwester Nawrocki wrote
> >>
> >> On 10/12/2012 10:47 PM, Ajay Kumar wrote:
> >>> This patch enables device tree based discovery support for DP driver.
> >>> The driver is modified to handle platform data in both the cases:
> >>> with DT and non-DT.
> >>>
> >>> Signed-off-by: Ajay Kumar<ajaykumar.rs@samsung.com>
> >>> Acked-by: Jingoo Han<jg1.han@samsung.com>
> >>> ---
> >>>    drivers/video/exynos/exynos_dp_core.c |  161 ++++++++++++++++++++++++++++++---
> >>>    drivers/video/exynos/exynos_dp_core.h |    2 +
> >>>    2 files changed, 149 insertions(+), 14 deletions(-)
> ...
> >>> @@ -953,8 +1062,13 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev)
> >>>    	struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
> >>>    	struct exynos_dp_device *dp = platform_get_drvdata(pdev);
> >>
> >> This doesn't belong to your patch, but the above 2 lines could be written as:
> >>
> >>    	struct exynos_dp_device *dp = dev_get_drvdata(&pdev->dev);
> >>
> >> Same in functions exynos_dp_suspend() and exynos_dp_resume().
> >
> > No, above 2 lines cannot be reduced to 1 line, as you mentioned.
> > This is because it makes build error.
> 
> Sorry, my bad. It looks fine in case of exynos_dp_remove().
> 
> But at exynos_dp_suspend/resume() there is something like:
> 
> 
> static int exynos_dp_suspend(struct device *dev)
> {
> 	struct platform_device *pdev = to_platform_device(dev);
> 	struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
> 	struct exynos_dp_device *dp = platform_get_drvdata(pdev);
> 
> 
> You need only pdata and dp there. I think that simpler form would
> do as well:
> 
> 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
> 	struct exynos_dp_platdata *pdata = dev->platform_data;

OK, I see.
I will accept your suggestion, because it is helpful to reduce
lines. Then, I will send v8 patch, soon.

> 
> 
> Sorry, this is just a nitpicking.
> 
> BTW, shouldn't CONFIG_EXYNOS_VIDEO depend on ARCH_EXYNOS ?
> 
> 
> --
> Regards,
> Sylwester
> --
> 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 V5 1/2] video: exynos_dp: Add device tree support to DP driver
From: Sylwester Nawrocki @ 2012-10-15 21:14 UTC (permalink / raw)
  To: Jingoo Han
  Cc: 'Ajay Kumar', linux-samsung-soc, linux-fbdev,
	devicetree-discuss, FlorianSchandinat, tomasz.figa, thomas.ab
In-Reply-To: <009d01cdaaad$0fa33230$2ee99690$%han@samsung.com>

On 10/15/2012 10:14 AM, Jingoo Han wrote:
> On Saturday, October 13, 2012 6:44 AM Sylwester Nawrocki wrote
>>
>> On 10/12/2012 10:47 PM, Ajay Kumar wrote:
>>> This patch enables device tree based discovery support for DP driver.
>>> The driver is modified to handle platform data in both the cases:
>>> with DT and non-DT.
>>>
>>> Signed-off-by: Ajay Kumar<ajaykumar.rs@samsung.com>
>>> Acked-by: Jingoo Han<jg1.han@samsung.com>
>>> ---
>>>    drivers/video/exynos/exynos_dp_core.c |  161 ++++++++++++++++++++++++++++++---
>>>    drivers/video/exynos/exynos_dp_core.h |    2 +
>>>    2 files changed, 149 insertions(+), 14 deletions(-)
...
>>> @@ -953,8 +1062,13 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev)
>>>    	struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
>>>    	struct exynos_dp_device *dp = platform_get_drvdata(pdev);
>>
>> This doesn't belong to your patch, but the above 2 lines could be written as:
>>
>>    	struct exynos_dp_device *dp = dev_get_drvdata(&pdev->dev);
>>
>> Same in functions exynos_dp_suspend() and exynos_dp_resume().
>
> No, above 2 lines cannot be reduced to 1 line, as you mentioned.
> This is because it makes build error.

Sorry, my bad. It looks fine in case of exynos_dp_remove().

But at exynos_dp_suspend/resume() there is something like:


static int exynos_dp_suspend(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
	struct exynos_dp_device *dp = platform_get_drvdata(pdev);


You need only pdata and dp there. I think that simpler form would
do as well:

	struct exynos_dp_device *dp = dev_get_drvdata(dev);
	struct exynos_dp_platdata *pdata = dev->platform_data;


Sorry, this is just a nitpicking.

BTW, shouldn't CONFIG_EXYNOS_VIDEO depend on ARCH_EXYNOS ?


--
Regards,
Sylwester

^ permalink raw reply

* Re: [PATCH 0/2 v6] of: add display helper
From: Steffen Trumtrar @ 2012-10-15 14:17 UTC (permalink / raw)
  To: Leela Krishna Amudala
  Cc: linux-fbdev, devicetree-discuss, dri-devel, Tomi Valkeinen,
	Laurent Pinchart, linux-media
In-Reply-To: <CAL1wa8fP8LBCUBVJS1=dy3cyFe+bY-Gu2+wtJyuCrgbP93m3Wg@mail.gmail.com>

Hi Leela,

On Mon, Oct 15, 2012 at 04:24:43PM +0530, Leela Krishna Amudala wrote:
> Hello Steffen,
> 
> To which version of the kernel we can expect this patch set to be merged into?
> Because I'm waiting for this from long time to add DT support for my
> display controller :)
> 

I have no idea, sorry. It seems like we have almost settled with the binding
(clock-name needs to be changed), but I'm not responsible for any merging/inclusions
in the kernel.

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

* Re: [PATCH 0/2 v6] of: add display helper
From: Leela Krishna Amudala @ 2012-10-15 10:55 UTC (permalink / raw)
  To: Steffen Trumtrar
  Cc: linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Tomi Valkeinen,
	Laurent Pinchart, linux-media-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1349373560-11128-1-git-send-email-s.trumtrar-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>

Hello Steffen,

To which version of the kernel we can expect this patch set to be merged into?
Because I'm waiting for this from long time to add DT support for my
display controller :)

Best Wishes,
Leela Krishna Amudala.

On Thu, Oct 4, 2012 at 11:29 PM, Steffen Trumtrar
<s.trumtrar@pengutronix.de> wrote:
>
> Hi!
>
> In accordance with Stepehn Warren, I downsized the binding.
> Now, just the display-timing is described, as I think, it is way easier to
> agree
> on those and have a complete binding.
>
> Regards,
> Steffen
>
> Steffen Trumtrar (2):
>   of: add helper to parse display timings
>   of: add generic videomode description
>
>  .../devicetree/bindings/video/display-timings.txt  |  222
> ++++++++++++++++++++
>  drivers/of/Kconfig                                 |   10 +
>  drivers/of/Makefile                                |    2 +
>  drivers/of/of_display_timings.c                    |  183
> ++++++++++++++++
>  drivers/of/of_videomode.c                          |  212
> +++++++++++++++++++
>  include/linux/of_display_timings.h                 |   85 ++++++++
>  include/linux/of_videomode.h                       |   41 ++++
>  7 files changed, 755 insertions(+)
>  create mode 100644
> Documentation/devicetree/bindings/video/display-timings.txt
>  create mode 100644 drivers/of/of_display_timings.c
>  create mode 100644 drivers/of/of_videomode.c
>  create mode 100644 include/linux/of_display_timings.h
>  create mode 100644 include/linux/of_videomode.h
>
> --
> 1.7.10.4
>
> --
> 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

* [PATCH V7 2/2] video: exynos_dp: device tree documentation
From: Jingoo Han @ 2012-10-15  9:57 UTC (permalink / raw)
  To: 'Florian Tobias Schandinat'
  Cc: linux-fbdev, linux-samsung-soc, devicetree-discuss,
	'Ajay Kumar', 'Sylwester Nawrocki',
	'Tomasz Figa', 'Thomas Abraham',
	'Jingoo Han'
In-Reply-To: <00a201cdaabb$5f6eb6f0$1e4c24d0$%han@samsung.com>

From: Ajay Kumar <ajaykumar.rs@samsung.com>

Add documentation for the DT bindings in exynos display port driver.

Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
No changes since v6:

 .../devicetree/bindings/video/exynos_dp.txt        |   80 ++++++++++++++++++++
 1 files changed, 80 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/video/exynos_dp.txt

diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt
new file mode 100644
index 0000000..7cc7d9f
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
@@ -0,0 +1,80 @@
+The Exynos display port interface should be configured based on
+the type of panel connected to it.
+
+We use two nodes:
+	-display-port-controller node
+	-dptx-phy node(defined inside display-port-controller node)
+
+For the DP-PHY initialization, we use the dptx-phy node.
+Required properties for dptx-phy:
+	-reg:
+		Base address of DP PHY register.
+	-samsung,enable-mask:
+		The bit-mask used to enable/disable DP PHY.
+
+For the Panel initialization, we read data from display-port-controller node.
+Required properties for display-port-controller:
+	-compatible:
+		should be "samsung,exynos5-dp".
+	-reg:
+		physical base address of the controller and length
+		of memory mapped region.
+	-interrupts:
+		interrupt combiner values.
+	-interrupt-parent:
+		phandle to Interrupt combiner node.
+	-samsung,color-space:
+		input video data format.
+			COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
+	-samsung,dynamic-range:
+		dynamic range for input video data.
+			VESA = 0, CEA = 1
+	-samsung,ycbcr-coeff:
+		YCbCr co-efficients for input video.
+			COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
+	-samsung,color-depth:
+		number of bits per colour component.
+			COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
+	-samsung,link-rate:
+		link rate supported by the panel.
+			LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A
+	-samsung,lane-count:
+		number of lanes supported by the panel.
+			LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
+
+Optional properties for display-port-controller:
+	-interlaced:
+		interlace scan mode.
+			Progressive if defined, Interlaced if not defined
+	-vsync-active-high:
+		VSYNC polarity configuration.
+			High if defined, Low if not defined
+	-hsync-active-high:
+		HSYNC polarity configuration.
+			High if defined, Low if not defined
+
+Example:
+
+SOC specific portion:
+	display-port-controller {
+		compatible = "samsung,exynos5-dp";
+		reg = <0x145b0000 0x10000>;
+		interrupts = <10 3>;
+		interrupt-parent = <&combiner>;
+
+		dptx-phy {
+			reg = <0x10040720>;
+			samsung,enable-mask = <1>;
+		};
+
+        };
+
+Board Specific portion:
+	display-port-controller {
+		samsung,color-space = <0>;
+		samsung,dynamic-range = <0>;
+		samsung,ycbcr-coeff = <0>;
+		samsung,color-depth = <1>;
+		samsung,link-rate = <0x0a>;
+		samsung,lane-count = <4>;
+	};
-- 
1.7.1



^ permalink raw reply related

* [PATCH V7 1/2] video: exynos_dp: Add device tree support to DP driver
From: Jingoo Han @ 2012-10-15  9:56 UTC (permalink / raw)
  To: 'Florian Tobias Schandinat'
  Cc: linux-fbdev, linux-samsung-soc, devicetree-discuss,
	'Ajay Kumar', 'Sylwester Nawrocki',
	'Tomasz Figa', 'Thomas Abraham',
	'Jingoo Han'

From: Ajay Kumar <ajaykumar.rs@samsung.com>

This patch enables device tree based discovery support for DP driver.
The driver is modified to handle platform data in both the cases:
with DT and non-DT.

Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
This patch is tested with Exynos5250.

Changes since v6:
- Fix return check for exynos_dp_dt_parse_phydata() in exynos_dp_probe()

 drivers/video/exynos/exynos_dp_core.c |  206 ++++++++++++++++++++++++++++++---
 drivers/video/exynos/exynos_dp_core.h |    2 +
 2 files changed, 194 insertions(+), 14 deletions(-)

diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index d55470e..0d9c0ee 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -18,6 +18,7 @@
 #include <linux/io.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/of.h>
 
 #include <video/exynos_dp.h>
 
@@ -856,6 +857,145 @@ static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
 	return IRQ_HANDLED;
 }
 
+#ifdef CONFIG_OF
+static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
+{
+	struct device_node *dp_node = dev->of_node;
+	struct exynos_dp_platdata *pd;
+	struct video_info *dp_video_config;
+
+	pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
+	if (!pd) {
+		dev_err(dev, "memory allocation for pdata failed\n");
+		return ERR_PTR(-ENOMEM);
+	}
+	dp_video_config = devm_kzalloc(dev,
+				sizeof(*dp_video_config), GFP_KERNEL);
+
+	if (!dp_video_config) {
+		dev_err(dev, "memory allocation for video config failed\n");
+		return ERR_PTR(-ENOMEM);
+	}
+	pd->video_info = dp_video_config;
+
+	dp_video_config->h_sync_polarity +		of_property_read_bool(dp_node, "hsync-active-high");
+
+	dp_video_config->v_sync_polarity +		of_property_read_bool(dp_node, "vsync-active-high");
+
+	dp_video_config->interlaced +		of_property_read_bool(dp_node, "interlaced");
+
+	if (of_property_read_u32(dp_node, "samsung,color-space",
+				&dp_video_config->color_space)) {
+		dev_err(dev, "failed to get color-space\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (of_property_read_u32(dp_node, "samsung,dynamic-range",
+				&dp_video_config->dynamic_range)) {
+		dev_err(dev, "failed to get dynamic-range\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (of_property_read_u32(dp_node, "samsung,ycbcr-coeff",
+				&dp_video_config->ycbcr_coeff)) {
+		dev_err(dev, "failed to get ycbcr-coeff\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (of_property_read_u32(dp_node, "samsung,color-depth",
+				&dp_video_config->color_depth)) {
+		dev_err(dev, "failed to get color-depth\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (of_property_read_u32(dp_node, "samsung,link-rate",
+				&dp_video_config->link_rate)) {
+		dev_err(dev, "failed to get link-rate\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (of_property_read_u32(dp_node, "samsung,lane-count",
+				&dp_video_config->lane_count)) {
+		dev_err(dev, "failed to get lane-count\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	return pd;
+}
+
+static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
+{
+	struct device_node *dp_phy_node;
+	u32 phy_base;
+
+	dp_phy_node = of_find_node_by_name(dp->dev->of_node, "dptx-phy");
+	if (!dp_phy_node) {
+		dev_err(dp->dev, "could not find dptx-phy node\n");
+		return -ENODEV;
+	}
+
+	if (of_property_read_u32(dp_phy_node, "reg", &phy_base)) {
+		dev_err(dp->dev, "faild to get reg for dptx-phy\n");
+		return -EINVAL;
+	}
+
+	if (of_property_read_u32(dp_phy_node, "samsung,enable-mask",
+				&dp->enable_mask)) {
+		dev_err(dp->dev, "faild to get enable-mask for dptx-phy\n");
+		return -EINVAL;
+	}
+
+	dp->phy_addr = ioremap(phy_base, SZ_4);
+	if (!dp->phy_addr) {
+		dev_err(dp->dev, "failed to ioremap dp-phy\n");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void exynos_dp_phy_init(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = __raw_readl(dp->phy_addr);
+	reg |= dp->enable_mask;
+	__raw_writel(reg, dp->phy_addr);
+}
+
+static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = __raw_readl(dp->phy_addr);
+	reg &= ~(dp->enable_mask);
+	__raw_writel(reg, dp->phy_addr);
+}
+#else
+static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
+{
+	return NULL;
+}
+
+static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
+{
+	return -EINVAL;
+}
+
+static void exynos_dp_phy_init(struct exynos_dp_device *dp)
+{
+	return;
+}
+
+static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
+{
+	return;
+}
+#endif /* CONFIG_OF */
+
 static int __devinit exynos_dp_probe(struct platform_device *pdev)
 {
 	struct resource *res;
@@ -864,12 +1004,6 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
 
 	int ret = 0;
 
-	pdata = pdev->dev.platform_data;
-	if (!pdata) {
-		dev_err(&pdev->dev, "no platform data\n");
-		return -EINVAL;
-	}
-
 	dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
 				GFP_KERNEL);
 	if (!dp) {
@@ -879,6 +1013,22 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
 
 	dp->dev = &pdev->dev;
 
+	if (pdev->dev.of_node) {
+		pdata = exynos_dp_dt_parse_pdata(&pdev->dev);
+		if (IS_ERR(pdata))
+			return PTR_ERR(pdata);
+
+		ret = exynos_dp_dt_parse_phydata(dp);
+		if (ret)
+			return ret;
+	} else {
+		pdata = pdev->dev.platform_data;
+		if (!pdata) {
+			dev_err(&pdev->dev, "no platform data\n");
+			return -EINVAL;
+		}
+	}
+
 	dp->clock = devm_clk_get(&pdev->dev, "dp");
 	if (IS_ERR(dp->clock)) {
 		dev_err(&pdev->dev, "failed to get clock\n");
@@ -909,8 +1059,14 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
 	}
 
 	dp->video_info = pdata->video_info;
-	if (pdata->phy_init)
-		pdata->phy_init();
+
+	if (pdev->dev.of_node) {
+		if (dp->phy_addr)
+			exynos_dp_phy_init(dp);
+	} else {
+		if (pdata->phy_init)
+			pdata->phy_init();
+	}
 
 	exynos_dp_init_dp(dp);
 
@@ -953,8 +1109,13 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev)
 	struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
 	struct exynos_dp_device *dp = platform_get_drvdata(pdev);
 
-	if (pdata && pdata->phy_exit)
-		pdata->phy_exit();
+	if (pdev->dev.of_node) {
+		if (dp->phy_addr)
+			exynos_dp_phy_exit(dp);
+	} else {
+		if (pdata->phy_exit)
+			pdata->phy_exit();
+	}
 
 	clk_disable_unprepare(dp->clock);
 
@@ -968,8 +1129,13 @@ static int exynos_dp_suspend(struct device *dev)
 	struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
 	struct exynos_dp_device *dp = platform_get_drvdata(pdev);
 
-	if (pdata && pdata->phy_exit)
-		pdata->phy_exit();
+	if (dev->of_node) {
+		if (dp->phy_addr)
+			exynos_dp_phy_exit(dp);
+	} else {
+		if (pdata->phy_exit)
+			pdata->phy_exit();
+	}
 
 	clk_disable_unprepare(dp->clock);
 
@@ -982,8 +1148,13 @@ static int exynos_dp_resume(struct device *dev)
 	struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
 	struct exynos_dp_device *dp = platform_get_drvdata(pdev);
 
-	if (pdata && pdata->phy_init)
-		pdata->phy_init();
+	if (dev->of_node) {
+		if (dp->phy_addr)
+			exynos_dp_phy_init(dp);
+	} else {
+		if (pdata->phy_init)
+			pdata->phy_init();
+	}
 
 	clk_prepare_enable(dp->clock);
 
@@ -1013,6 +1184,12 @@ static const struct dev_pm_ops exynos_dp_pm_ops = {
 	SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume)
 };
 
+static const struct of_device_id exynos_dp_match[] = {
+	{ .compatible = "samsung,exynos5-dp" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, exynos_dp_match);
+
 static struct platform_driver exynos_dp_driver = {
 	.probe		= exynos_dp_probe,
 	.remove		= __devexit_p(exynos_dp_remove),
@@ -1020,6 +1197,7 @@ static struct platform_driver exynos_dp_driver = {
 		.name	= "exynos-dp",
 		.owner	= THIS_MODULE,
 		.pm	= &exynos_dp_pm_ops,
+		.of_match_table = of_match_ptr(exynos_dp_match),
 	},
 };
 
diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h
index 57b8a65..6dbeeb2 100644
--- a/drivers/video/exynos/exynos_dp_core.h
+++ b/drivers/video/exynos/exynos_dp_core.h
@@ -29,6 +29,8 @@ struct exynos_dp_device {
 	struct clk		*clock;
 	unsigned int		irq;
 	void __iomem		*reg_base;
+	void __iomem		*phy_addr;
+	unsigned int		enable_mask;
 
 	struct video_info	*video_info;
 	struct link_train	link_train;
-- 
1.7.1



^ permalink raw reply related

* RE: [PATCH V6 1/2] video: exynos_dp: Add device tree support to DP driver
From: Jingoo Han @ 2012-10-15  9:44 UTC (permalink / raw)
  To: 'Florian Tobias Schandinat'
  Cc: linux-fbdev, linux-samsung-soc, devicetree-discuss,
	'Ajay Kumar', 'Sylwester Nawrocki',
	'Tomasz Figa', 'Thomas Abraham',
	'Jingoo Han'
In-Reply-To: <009e01cdaab5$25cff2c0$716fd840$%han@samsung.com>

On Monday, October 15, 2012 6:12 PM Jingoo Han wrote
> 
> From: Ajay Kumar <ajaykumar.rs@samsung.com>
> 
> This patch enables device tree based discovery support for DP driver.
> The driver is modified to handle platform data in both the cases:
> with DT and non-DT.
> 
> Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
> Signed-off-by: Jingoo Han <jg1.han@samsung.com>
> ---
> This patch is tested with Exynos5250.
> 
> Changes since v6:
> - Check return values of required properties
> - Replace dp_phy_addr with phy_addr
> - Remove unnecessary NULL deference checking for 'pdata'
> - Remove unncessary 'virt_phy_base' variable
> - Make functions static
> - Fix build errors when CONFIG_OF option is diabled
> - Add return values to exynos_dp_dt_parse_phydata()
> 
>  drivers/video/exynos/exynos_dp_core.c |  206 ++++++++++++++++++++++++++++++---
>  drivers/video/exynos/exynos_dp_core.h |    2 +
>  2 files changed, 194 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
> index d55470e..0d9c0ee 100644
> --- a/drivers/video/exynos/exynos_dp_core.c
> +++ b/drivers/video/exynos/exynos_dp_core.c
> @@ -18,6 +18,7 @@
>  #include <linux/io.h>
>  #include <linux/interrupt.h>
>  #include <linux/delay.h>
> +#include <linux/of.h>
> 
>  #include <video/exynos_dp.h>
> 
> @@ -856,6 +857,145 @@ static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
>  	return IRQ_HANDLED;
>  }
> 
> +#ifdef CONFIG_OF
> +static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
> +{
> +	struct device_node *dp_node = dev->of_node;
> +	struct exynos_dp_platdata *pd;
> +	struct video_info *dp_video_config;
> +
> +	pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
> +	if (!pd) {
> +		dev_err(dev, "memory allocation for pdata failed\n");
> +		return ERR_PTR(-ENOMEM);
> +	}
> +	dp_video_config = devm_kzalloc(dev,
> +				sizeof(*dp_video_config), GFP_KERNEL);
> +
> +	if (!dp_video_config) {
> +		dev_err(dev, "memory allocation for video config failed\n");
> +		return ERR_PTR(-ENOMEM);
> +	}
> +	pd->video_info = dp_video_config;
> +
> +	dp_video_config->h_sync_polarity > +		of_property_read_bool(dp_node, "hsync-active-high");
> +
> +	dp_video_config->v_sync_polarity > +		of_property_read_bool(dp_node, "vsync-active-high");
> +
> +	dp_video_config->interlaced > +		of_property_read_bool(dp_node, "interlaced");
> +
> +	if (of_property_read_u32(dp_node, "samsung,color-space",
> +				&dp_video_config->color_space)) {
> +		dev_err(dev, "failed to get color-space\n");
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	if (of_property_read_u32(dp_node, "samsung,dynamic-range",
> +				&dp_video_config->dynamic_range)) {
> +		dev_err(dev, "failed to get dynamic-range\n");
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	if (of_property_read_u32(dp_node, "samsung,ycbcr-coeff",
> +				&dp_video_config->ycbcr_coeff)) {
> +		dev_err(dev, "failed to get ycbcr-coeff\n");
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	if (of_property_read_u32(dp_node, "samsung,color-depth",
> +				&dp_video_config->color_depth)) {
> +		dev_err(dev, "failed to get color-depth\n");
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	if (of_property_read_u32(dp_node, "samsung,link-rate",
> +				&dp_video_config->link_rate)) {
> +		dev_err(dev, "failed to get link-rate\n");
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	if (of_property_read_u32(dp_node, "samsung,lane-count",
> +				&dp_video_config->lane_count)) {
> +		dev_err(dev, "failed to get lane-count\n");
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	return pd;
> +}
> +
> +static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
> +{
> +	struct device_node *dp_phy_node;
> +	u32 phy_base;
> +
> +	dp_phy_node = of_find_node_by_name(dp->dev->of_node, "dptx-phy");
> +	if (!dp_phy_node) {
> +		dev_err(dp->dev, "could not find dptx-phy node\n");
> +		return -ENODEV;
> +	}
> +
> +	if (of_property_read_u32(dp_phy_node, "reg", &phy_base)) {
> +		dev_err(dp->dev, "faild to get reg for dptx-phy\n");
> +		return -EINVAL;
> +	}
> +
> +	if (of_property_read_u32(dp_phy_node, "samsung,enable-mask",
> +				&dp->enable_mask)) {
> +		dev_err(dp->dev, "faild to get enable-mask for dptx-phy\n");
> +		return -EINVAL;
> +	}
> +
> +	dp->phy_addr = ioremap(phy_base, SZ_4);
> +	if (!dp->phy_addr) {
> +		dev_err(dp->dev, "failed to ioremap dp-phy\n");
> +		return -ENOMEM;
> +	}
> +
> +	return 0;
> +}
> +
> +static void exynos_dp_phy_init(struct exynos_dp_device *dp)
> +{
> +	u32 reg;
> +
> +	reg = __raw_readl(dp->phy_addr);
> +	reg |= dp->enable_mask;
> +	__raw_writel(reg, dp->phy_addr);
> +}
> +
> +static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
> +{
> +	u32 reg;
> +
> +	reg = __raw_readl(dp->phy_addr);
> +	reg &= ~(dp->enable_mask);
> +	__raw_writel(reg, dp->phy_addr);
> +}
> +#else
> +static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
> +{
> +	return NULL;
> +}
> +
> +static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
> +{
> +	return -EINVAL;
> +}
> +
> +static void exynos_dp_phy_init(struct exynos_dp_device *dp)
> +{
> +	return;
> +}
> +
> +static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
> +{
> +	return;
> +}
> +#endif /* CONFIG_OF */
> +
>  static int __devinit exynos_dp_probe(struct platform_device *pdev)
>  {
>  	struct resource *res;
> @@ -864,12 +1004,6 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
> 
>  	int ret = 0;
> 
> -	pdata = pdev->dev.platform_data;
> -	if (!pdata) {
> -		dev_err(&pdev->dev, "no platform data\n");
> -		return -EINVAL;
> -	}
> -
>  	dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
>  				GFP_KERNEL);
>  	if (!dp) {
> @@ -879,6 +1013,22 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
> 
>  	dp->dev = &pdev->dev;
> 
> +	if (pdev->dev.of_node) {
> +		pdata = exynos_dp_dt_parse_pdata(&pdev->dev);
> +		if (IS_ERR(pdata))
> +			return PTR_ERR(pdata);
> +
> +		ret = exynos_dp_dt_parse_phydata(dp);
> +		if (!ret)

It should be 'if (ret)' instead of 'if (!ret)'.
It is my fault. I will send v7 patch, soon.

Sorry.

> +			return ret;
> +	} else {
> +		pdata = pdev->dev.platform_data;
> +		if (!pdata) {
> +			dev_err(&pdev->dev, "no platform data\n");
> +			return -EINVAL;
> +		}
> +	}
> +
>  	dp->clock = devm_clk_get(&pdev->dev, "dp");
>  	if (IS_ERR(dp->clock)) {
>  		dev_err(&pdev->dev, "failed to get clock\n");
> @@ -909,8 +1059,14 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
>  	}
> 
>  	dp->video_info = pdata->video_info;
> -	if (pdata->phy_init)
> -		pdata->phy_init();
> +
> +	if (pdev->dev.of_node) {
> +		if (dp->phy_addr)
> +			exynos_dp_phy_init(dp);
> +	} else {
> +		if (pdata->phy_init)
> +			pdata->phy_init();
> +	}
> 
>  	exynos_dp_init_dp(dp);
> 
> @@ -953,8 +1109,13 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev)
>  	struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
>  	struct exynos_dp_device *dp = platform_get_drvdata(pdev);
> 
> -	if (pdata && pdata->phy_exit)
> -		pdata->phy_exit();
> +	if (pdev->dev.of_node) {
> +		if (dp->phy_addr)
> +			exynos_dp_phy_exit(dp);
> +	} else {
> +		if (pdata->phy_exit)
> +			pdata->phy_exit();
> +	}
> 
>  	clk_disable_unprepare(dp->clock);
> 
> @@ -968,8 +1129,13 @@ static int exynos_dp_suspend(struct device *dev)
>  	struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
>  	struct exynos_dp_device *dp = platform_get_drvdata(pdev);
> 
> -	if (pdata && pdata->phy_exit)
> -		pdata->phy_exit();
> +	if (dev->of_node) {
> +		if (dp->phy_addr)
> +			exynos_dp_phy_exit(dp);
> +	} else {
> +		if (pdata->phy_exit)
> +			pdata->phy_exit();
> +	}
> 
>  	clk_disable_unprepare(dp->clock);
> 
> @@ -982,8 +1148,13 @@ static int exynos_dp_resume(struct device *dev)
>  	struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
>  	struct exynos_dp_device *dp = platform_get_drvdata(pdev);
> 
> -	if (pdata && pdata->phy_init)
> -		pdata->phy_init();
> +	if (dev->of_node) {
> +		if (dp->phy_addr)
> +			exynos_dp_phy_init(dp);
> +	} else {
> +		if (pdata->phy_init)
> +			pdata->phy_init();
> +	}
> 
>  	clk_prepare_enable(dp->clock);
> 
> @@ -1013,6 +1184,12 @@ static const struct dev_pm_ops exynos_dp_pm_ops = {
>  	SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume)
>  };
> 
> +static const struct of_device_id exynos_dp_match[] = {
> +	{ .compatible = "samsung,exynos5-dp" },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, exynos_dp_match);
> +
>  static struct platform_driver exynos_dp_driver = {
>  	.probe		= exynos_dp_probe,
>  	.remove		= __devexit_p(exynos_dp_remove),
> @@ -1020,6 +1197,7 @@ static struct platform_driver exynos_dp_driver = {
>  		.name	= "exynos-dp",
>  		.owner	= THIS_MODULE,
>  		.pm	= &exynos_dp_pm_ops,
> +		.of_match_table = of_match_ptr(exynos_dp_match),
>  	},
>  };
> 
> diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h
> index 57b8a65..6dbeeb2 100644
> --- a/drivers/video/exynos/exynos_dp_core.h
> +++ b/drivers/video/exynos/exynos_dp_core.h
> @@ -29,6 +29,8 @@ struct exynos_dp_device {
>  	struct clk		*clock;
>  	unsigned int		irq;
>  	void __iomem		*reg_base;
> +	void __iomem		*phy_addr;
> +	unsigned int		enable_mask;
> 
>  	struct video_info	*video_info;
>  	struct link_train	link_train;
> --
> 1.7.1



^ permalink raw reply

* [PATCH V6 2/2] video: exynos_dp: device tree documentation
From: Jingoo Han @ 2012-10-15  9:13 UTC (permalink / raw)
  To: 'Florian Tobias Schandinat'
  Cc: linux-fbdev, linux-samsung-soc, devicetree-discuss,
	'Ajay Kumar', 'Sylwester Nawrocki',
	'Tomasz Figa', 'Thomas Abraham',
	'Jingoo Han'
In-Reply-To: <009e01cdaab5$25cff2c0$716fd840$%han@samsung.com>

From: Ajay Kumar <ajaykumar.rs@samsung.com>

Add documentation for the DT bindings in exynos display port driver.

Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
Changes since v6:
- Remove duplicated 'based on'

 .../devicetree/bindings/video/exynos_dp.txt        |   80 ++++++++++++++++++++
 1 files changed, 80 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/video/exynos_dp.txt

diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt
new file mode 100644
index 0000000..7cc7d9f
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
@@ -0,0 +1,80 @@
+The Exynos display port interface should be configured based on
+the type of panel connected to it.
+
+We use two nodes:
+	-display-port-controller node
+	-dptx-phy node(defined inside display-port-controller node)
+
+For the DP-PHY initialization, we use the dptx-phy node.
+Required properties for dptx-phy:
+	-reg:
+		Base address of DP PHY register.
+	-samsung,enable-mask:
+		The bit-mask used to enable/disable DP PHY.
+
+For the Panel initialization, we read data from display-port-controller node.
+Required properties for display-port-controller:
+	-compatible:
+		should be "samsung,exynos5-dp".
+	-reg:
+		physical base address of the controller and length
+		of memory mapped region.
+	-interrupts:
+		interrupt combiner values.
+	-interrupt-parent:
+		phandle to Interrupt combiner node.
+	-samsung,color-space:
+		input video data format.
+			COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
+	-samsung,dynamic-range:
+		dynamic range for input video data.
+			VESA = 0, CEA = 1
+	-samsung,ycbcr-coeff:
+		YCbCr co-efficients for input video.
+			COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
+	-samsung,color-depth:
+		number of bits per colour component.
+			COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
+	-samsung,link-rate:
+		link rate supported by the panel.
+			LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A
+	-samsung,lane-count:
+		number of lanes supported by the panel.
+			LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
+
+Optional properties for display-port-controller:
+	-interlaced:
+		interlace scan mode.
+			Progressive if defined, Interlaced if not defined
+	-vsync-active-high:
+		VSYNC polarity configuration.
+			High if defined, Low if not defined
+	-hsync-active-high:
+		HSYNC polarity configuration.
+			High if defined, Low if not defined
+
+Example:
+
+SOC specific portion:
+	display-port-controller {
+		compatible = "samsung,exynos5-dp";
+		reg = <0x145b0000 0x10000>;
+		interrupts = <10 3>;
+		interrupt-parent = <&combiner>;
+
+		dptx-phy {
+			reg = <0x10040720>;
+			samsung,enable-mask = <1>;
+		};
+
+        };
+
+Board Specific portion:
+	display-port-controller {
+		samsung,color-space = <0>;
+		samsung,dynamic-range = <0>;
+		samsung,ycbcr-coeff = <0>;
+		samsung,color-depth = <1>;
+		samsung,link-rate = <0x0a>;
+		samsung,lane-count = <4>;
+	};
-- 
1.7.1



^ permalink raw reply related

* [PATCH V6 1/2] video: exynos_dp: Add device tree support to DP driver
From: Jingoo Han @ 2012-10-15  9:12 UTC (permalink / raw)
  To: 'Florian Tobias Schandinat'
  Cc: linux-fbdev, linux-samsung-soc, devicetree-discuss,
	'Ajay Kumar', 'Sylwester Nawrocki',
	'Tomasz Figa', 'Thomas Abraham',
	'Jingoo Han'

From: Ajay Kumar <ajaykumar.rs@samsung.com>

This patch enables device tree based discovery support for DP driver.
The driver is modified to handle platform data in both the cases:
with DT and non-DT.

Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
This patch is tested with Exynos5250.

Changes since v6:
- Check return values of required properties
- Replace dp_phy_addr with phy_addr
- Remove unnecessary NULL deference checking for 'pdata'
- Remove unncessary 'virt_phy_base' variable
- Make functions static
- Fix build errors when CONFIG_OF option is diabled
- Add return values to exynos_dp_dt_parse_phydata()

 drivers/video/exynos/exynos_dp_core.c |  206 ++++++++++++++++++++++++++++++---
 drivers/video/exynos/exynos_dp_core.h |    2 +
 2 files changed, 194 insertions(+), 14 deletions(-)

diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index d55470e..0d9c0ee 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -18,6 +18,7 @@
 #include <linux/io.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/of.h>
 
 #include <video/exynos_dp.h>
 
@@ -856,6 +857,145 @@ static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
 	return IRQ_HANDLED;
 }
 
+#ifdef CONFIG_OF
+static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
+{
+	struct device_node *dp_node = dev->of_node;
+	struct exynos_dp_platdata *pd;
+	struct video_info *dp_video_config;
+
+	pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
+	if (!pd) {
+		dev_err(dev, "memory allocation for pdata failed\n");
+		return ERR_PTR(-ENOMEM);
+	}
+	dp_video_config = devm_kzalloc(dev,
+				sizeof(*dp_video_config), GFP_KERNEL);
+
+	if (!dp_video_config) {
+		dev_err(dev, "memory allocation for video config failed\n");
+		return ERR_PTR(-ENOMEM);
+	}
+	pd->video_info = dp_video_config;
+
+	dp_video_config->h_sync_polarity +		of_property_read_bool(dp_node, "hsync-active-high");
+
+	dp_video_config->v_sync_polarity +		of_property_read_bool(dp_node, "vsync-active-high");
+
+	dp_video_config->interlaced +		of_property_read_bool(dp_node, "interlaced");
+
+	if (of_property_read_u32(dp_node, "samsung,color-space",
+				&dp_video_config->color_space)) {
+		dev_err(dev, "failed to get color-space\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (of_property_read_u32(dp_node, "samsung,dynamic-range",
+				&dp_video_config->dynamic_range)) {
+		dev_err(dev, "failed to get dynamic-range\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (of_property_read_u32(dp_node, "samsung,ycbcr-coeff",
+				&dp_video_config->ycbcr_coeff)) {
+		dev_err(dev, "failed to get ycbcr-coeff\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (of_property_read_u32(dp_node, "samsung,color-depth",
+				&dp_video_config->color_depth)) {
+		dev_err(dev, "failed to get color-depth\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (of_property_read_u32(dp_node, "samsung,link-rate",
+				&dp_video_config->link_rate)) {
+		dev_err(dev, "failed to get link-rate\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (of_property_read_u32(dp_node, "samsung,lane-count",
+				&dp_video_config->lane_count)) {
+		dev_err(dev, "failed to get lane-count\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	return pd;
+}
+
+static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
+{
+	struct device_node *dp_phy_node;
+	u32 phy_base;
+
+	dp_phy_node = of_find_node_by_name(dp->dev->of_node, "dptx-phy");
+	if (!dp_phy_node) {
+		dev_err(dp->dev, "could not find dptx-phy node\n");
+		return -ENODEV;
+	}
+
+	if (of_property_read_u32(dp_phy_node, "reg", &phy_base)) {
+		dev_err(dp->dev, "faild to get reg for dptx-phy\n");
+		return -EINVAL;
+	}
+
+	if (of_property_read_u32(dp_phy_node, "samsung,enable-mask",
+				&dp->enable_mask)) {
+		dev_err(dp->dev, "faild to get enable-mask for dptx-phy\n");
+		return -EINVAL;
+	}
+
+	dp->phy_addr = ioremap(phy_base, SZ_4);
+	if (!dp->phy_addr) {
+		dev_err(dp->dev, "failed to ioremap dp-phy\n");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void exynos_dp_phy_init(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = __raw_readl(dp->phy_addr);
+	reg |= dp->enable_mask;
+	__raw_writel(reg, dp->phy_addr);
+}
+
+static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = __raw_readl(dp->phy_addr);
+	reg &= ~(dp->enable_mask);
+	__raw_writel(reg, dp->phy_addr);
+}
+#else
+static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
+{
+	return NULL;
+}
+
+static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
+{
+	return -EINVAL;
+}
+
+static void exynos_dp_phy_init(struct exynos_dp_device *dp)
+{
+	return;
+}
+
+static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
+{
+	return;
+}
+#endif /* CONFIG_OF */
+
 static int __devinit exynos_dp_probe(struct platform_device *pdev)
 {
 	struct resource *res;
@@ -864,12 +1004,6 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
 
 	int ret = 0;
 
-	pdata = pdev->dev.platform_data;
-	if (!pdata) {
-		dev_err(&pdev->dev, "no platform data\n");
-		return -EINVAL;
-	}
-
 	dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
 				GFP_KERNEL);
 	if (!dp) {
@@ -879,6 +1013,22 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
 
 	dp->dev = &pdev->dev;
 
+	if (pdev->dev.of_node) {
+		pdata = exynos_dp_dt_parse_pdata(&pdev->dev);
+		if (IS_ERR(pdata))
+			return PTR_ERR(pdata);
+
+		ret = exynos_dp_dt_parse_phydata(dp);
+		if (!ret)
+			return ret;
+	} else {
+		pdata = pdev->dev.platform_data;
+		if (!pdata) {
+			dev_err(&pdev->dev, "no platform data\n");
+			return -EINVAL;
+		}
+	}
+
 	dp->clock = devm_clk_get(&pdev->dev, "dp");
 	if (IS_ERR(dp->clock)) {
 		dev_err(&pdev->dev, "failed to get clock\n");
@@ -909,8 +1059,14 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
 	}
 
 	dp->video_info = pdata->video_info;
-	if (pdata->phy_init)
-		pdata->phy_init();
+
+	if (pdev->dev.of_node) {
+		if (dp->phy_addr)
+			exynos_dp_phy_init(dp);
+	} else {
+		if (pdata->phy_init)
+			pdata->phy_init();
+	}
 
 	exynos_dp_init_dp(dp);
 
@@ -953,8 +1109,13 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev)
 	struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
 	struct exynos_dp_device *dp = platform_get_drvdata(pdev);
 
-	if (pdata && pdata->phy_exit)
-		pdata->phy_exit();
+	if (pdev->dev.of_node) {
+		if (dp->phy_addr)
+			exynos_dp_phy_exit(dp);
+	} else {
+		if (pdata->phy_exit)
+			pdata->phy_exit();
+	}
 
 	clk_disable_unprepare(dp->clock);
 
@@ -968,8 +1129,13 @@ static int exynos_dp_suspend(struct device *dev)
 	struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
 	struct exynos_dp_device *dp = platform_get_drvdata(pdev);
 
-	if (pdata && pdata->phy_exit)
-		pdata->phy_exit();
+	if (dev->of_node) {
+		if (dp->phy_addr)
+			exynos_dp_phy_exit(dp);
+	} else {
+		if (pdata->phy_exit)
+			pdata->phy_exit();
+	}
 
 	clk_disable_unprepare(dp->clock);
 
@@ -982,8 +1148,13 @@ static int exynos_dp_resume(struct device *dev)
 	struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
 	struct exynos_dp_device *dp = platform_get_drvdata(pdev);
 
-	if (pdata && pdata->phy_init)
-		pdata->phy_init();
+	if (dev->of_node) {
+		if (dp->phy_addr)
+			exynos_dp_phy_init(dp);
+	} else {
+		if (pdata->phy_init)
+			pdata->phy_init();
+	}
 
 	clk_prepare_enable(dp->clock);
 
@@ -1013,6 +1184,12 @@ static const struct dev_pm_ops exynos_dp_pm_ops = {
 	SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume)
 };
 
+static const struct of_device_id exynos_dp_match[] = {
+	{ .compatible = "samsung,exynos5-dp" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, exynos_dp_match);
+
 static struct platform_driver exynos_dp_driver = {
 	.probe		= exynos_dp_probe,
 	.remove		= __devexit_p(exynos_dp_remove),
@@ -1020,6 +1197,7 @@ static struct platform_driver exynos_dp_driver = {
 		.name	= "exynos-dp",
 		.owner	= THIS_MODULE,
 		.pm	= &exynos_dp_pm_ops,
+		.of_match_table = of_match_ptr(exynos_dp_match),
 	},
 };
 
diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h
index 57b8a65..6dbeeb2 100644
--- a/drivers/video/exynos/exynos_dp_core.h
+++ b/drivers/video/exynos/exynos_dp_core.h
@@ -29,6 +29,8 @@ struct exynos_dp_device {
 	struct clk		*clock;
 	unsigned int		irq;
 	void __iomem		*reg_base;
+	void __iomem		*phy_addr;
+	unsigned int		enable_mask;
 
 	struct video_info	*video_info;
 	struct link_train	link_train;
-- 
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