Linux Framebuffer Layer development
 help / color / mirror / Atom feed
* [PATCH] fsl-diu-fb: remove the ioctl interface
From: Timur Tabi @ 2011-06-21 21:27 UTC (permalink / raw)
  To: lethal, linux-fbdev, agust, yorksun, linuxppc-dev

The ioctl interface in the Freescale DIU framebuffer driver is just a
collection of miscellaneous functions which were only used in a one-time
demo application that was never distributed.  Plus, the ioctls were spread
across two types (both conflicting), and the demo app didn't even use all
of them.

Removing the ioctl interface also allows us to clean up the header file and
remove other unusued stuff.

Signed-off-by: Timur Tabi <timur@freescale.com>
---

There's a warning about dummy_ad_addr that will be fixed in a future patch.

 Documentation/ioctl/ioctl-number.txt |    2 -
 drivers/video/fsl-diu-fb.c           |  157 ++++++++++------------------------
 include/linux/fsl-diu-fb.h           |   94 --------------------
 3 files changed, 44 insertions(+), 209 deletions(-)

diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt
index 3a46e36..6c83c07 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -108,7 +108,6 @@ Code  Seq#(hex)	Include File		Comments
 'E'	00-0F	xen/evtchn.h		conflict!
 'F'	all	linux/fb.h		conflict!
 'F'	01-02	drivers/scsi/pmcraid.h	conflict!
-'F'	20	drivers/video/fsl-diu-fb.h	conflict!
 'F'	20	drivers/video/intelfb/intelfb.h	conflict!
 'F'	20	linux/ivtvfb.h		conflict!
 'F'	20	linux/matroxfb.h	conflict!
@@ -147,7 +146,6 @@ Code  Seq#(hex)	Include File		Comments
 'M'	01-16	mtd/mtd-abi.h		conflict!
 		and drivers/mtd/mtdchar.c
 'M'	01-03	drivers/scsi/megaraid/megaraid_sas.h
-'M'	00-0F	drivers/video/fsl-diu-fb.h	conflict!
 'N'	00-1F	drivers/usb/scanner.h
 'O'     00-06   mtd/ubi-user.h		UBI
 'P'	all	linux/soundcard.h	conflict!
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index bedf5be..db2abaf 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -37,6 +37,50 @@
 #include <linux/fsl-diu-fb.h>
 #include "edid.h"
 
+/* Minimum value that the pixel clock can be set to in pico seconds
+ * This is determined by platform clock/3 where the minimum platform
+ * clock is 533MHz. This gives 5629 pico seconds.
+ */
+#define MIN_PIX_CLK	5629
+#define MAX_PIX_CLK	96096
+
+#define FSL_AOI_NUM	6	/* 5 AOIs and one dummy AOI */
+
+/* INT_STATUS/INT_MASK field descriptions */
+#define INT_VSYNC	0x01	/* Vsync interrupt  */
+#define INT_VSYNC_WB	0x02	/* Vsync interrupt for write back operation */
+#define INT_UNDRUN	0x04	/* Under run exception interrupt */
+#define INT_PARERR	0x08	/* Display parameters error interrupt */
+#define INT_LS_BF_VS	0x10	/* Lines before vsync. interrupt */
+
+/* Panels'operation modes */
+#define MFB_TYPE_OUTPUT	0	/* Panel output to display */
+#define MFB_TYPE_OFF	1	/* Panel off */
+#define MFB_TYPE_WB	2	/* Panel written back to memory */
+#define MFB_TYPE_TEST	3	/* Panel generate color bar */
+
+/* HW cursor parameters */
+#define MAX_CURS	32
+
+struct diu_hw {
+	struct diu *diu_reg;
+	spinlock_t reg_lock;
+	__u32 mode;		/* DIU operation mode */
+};
+
+struct diu_addr {
+	__u8 __iomem *vaddr;	/* Virtual address */
+	dma_addr_t paddr;	/* Physical address */
+	__u32 offset;
+};
+
+struct diu_pool {
+	struct diu_addr ad;
+	struct diu_addr gamma;
+	struct diu_addr pallete;
+	struct diu_addr cursor;
+};
+
 /*
  * These parameters give default parameters
  * for video output 1024x768,
@@ -991,118 +1035,6 @@ static int fsl_diu_blank(int blank_mode, struct fb_info *info)
 	return 0;
 }
 
-static int fsl_diu_ioctl(struct fb_info *info, unsigned int cmd,
-		       unsigned long arg)
-{
-	struct mfb_info *mfbi = info->par;
-	struct diu_ad *ad = mfbi->ad;
-	struct mfb_chroma_key ck;
-	unsigned char global_alpha;
-	struct aoi_display_offset aoi_d;
-	__u32 pix_fmt;
-	void __user *buf = (void __user *)arg;
-
-	if (!arg)
-		return -EINVAL;
-	switch (cmd) {
-	case MFB_SET_PIXFMT:
-		if (copy_from_user(&pix_fmt, buf, sizeof(pix_fmt)))
-			return -EFAULT;
-		ad->pix_fmt = pix_fmt;
-		pr_debug("Set pixel format to 0x%08x\n", ad->pix_fmt);
-		break;
-	case MFB_GET_PIXFMT:
-		pix_fmt = ad->pix_fmt;
-		if (copy_to_user(buf, &pix_fmt, sizeof(pix_fmt)))
-			return -EFAULT;
-		pr_debug("get pixel format 0x%08x\n", ad->pix_fmt);
-		break;
-	case MFB_SET_AOID:
-		if (copy_from_user(&aoi_d, buf, sizeof(aoi_d)))
-			return -EFAULT;
-		mfbi->x_aoi_d = aoi_d.x_aoi_d;
-		mfbi->y_aoi_d = aoi_d.y_aoi_d;
-		pr_debug("set AOI display offset of index %d to (%d,%d)\n",
-				 mfbi->index, aoi_d.x_aoi_d, aoi_d.y_aoi_d);
-		fsl_diu_check_var(&info->var, info);
-		fsl_diu_set_aoi(info);
-		break;
-	case MFB_GET_AOID:
-		aoi_d.x_aoi_d = mfbi->x_aoi_d;
-		aoi_d.y_aoi_d = mfbi->y_aoi_d;
-		if (copy_to_user(buf, &aoi_d, sizeof(aoi_d)))
-			return -EFAULT;
-		pr_debug("get AOI display offset of index %d (%d,%d)\n",
-				mfbi->index, aoi_d.x_aoi_d, aoi_d.y_aoi_d);
-		break;
-	case MFB_GET_ALPHA:
-		global_alpha = mfbi->g_alpha;
-		if (copy_to_user(buf, &global_alpha, sizeof(global_alpha)))
-			return -EFAULT;
-		pr_debug("get global alpha of index %d\n", mfbi->index);
-		break;
-	case MFB_SET_ALPHA:
-		/* set panel information */
-		if (copy_from_user(&global_alpha, buf, sizeof(global_alpha)))
-			return -EFAULT;
-		ad->src_size_g_alpha = (ad->src_size_g_alpha & (~0xff)) |
-							(global_alpha & 0xff);
-		mfbi->g_alpha = global_alpha;
-		pr_debug("set global alpha for index %d\n", mfbi->index);
-		break;
-	case MFB_SET_CHROMA_KEY:
-		/* set panel winformation */
-		if (copy_from_user(&ck, buf, sizeof(ck)))
-			return -EFAULT;
-
-		if (ck.enable &&
-		   (ck.red_max < ck.red_min ||
-		    ck.green_max < ck.green_min ||
-		    ck.blue_max < ck.blue_min))
-			return -EINVAL;
-
-		if (!ck.enable) {
-			ad->ckmax_r = 0;
-			ad->ckmax_g = 0;
-			ad->ckmax_b = 0;
-			ad->ckmin_r = 255;
-			ad->ckmin_g = 255;
-			ad->ckmin_b = 255;
-		} else {
-			ad->ckmax_r = ck.red_max;
-			ad->ckmax_g = ck.green_max;
-			ad->ckmax_b = ck.blue_max;
-			ad->ckmin_r = ck.red_min;
-			ad->ckmin_g = ck.green_min;
-			ad->ckmin_b = ck.blue_min;
-		}
-		pr_debug("set chroma key\n");
-		break;
-	case FBIOGET_GWINFO:
-		if (mfbi->type = MFB_TYPE_OFF)
-			return -ENODEV;
-		/* get graphic window information */
-		if (copy_to_user(buf, ad, sizeof(*ad)))
-			return -EFAULT;
-		break;
-	case FBIOGET_HWCINFO:
-		pr_debug("FBIOGET_HWCINFO:0x%08x\n", FBIOGET_HWCINFO);
-		break;
-	case FBIOPUT_MODEINFO:
-		pr_debug("FBIOPUT_MODEINFO:0x%08x\n", FBIOPUT_MODEINFO);
-		break;
-	case FBIOGET_DISPINFO:
-		pr_debug("FBIOGET_DISPINFO:0x%08x\n", FBIOGET_DISPINFO);
-		break;
-
-	default:
-		printk(KERN_ERR "Unknown ioctl command (0x%08X)\n", cmd);
-		return -ENOIOCTLCMD;
-	}
-
-	return 0;
-}
-
 /* turn on fb if count = 1
  */
 static int fsl_diu_open(struct fb_info *info, int user)
@@ -1162,7 +1094,6 @@ static struct fb_ops fsl_diu_ops = {
 	.fb_fillrect = cfb_fillrect,
 	.fb_copyarea = cfb_copyarea,
 	.fb_imageblit = cfb_imageblit,
-	.fb_ioctl = fsl_diu_ioctl,
 	.fb_open = fsl_diu_open,
 	.fb_release = fsl_diu_release,
 };
diff --git a/include/linux/fsl-diu-fb.h b/include/linux/fsl-diu-fb.h
index 781d467..234c38e 100644
--- a/include/linux/fsl-diu-fb.h
+++ b/include/linux/fsl-diu-fb.h
@@ -20,55 +20,8 @@
 #ifndef __FSL_DIU_FB_H__
 #define __FSL_DIU_FB_H__
 
-/* Arbitrary threshold to determine the allocation method
- * See mpc8610fb_set_par(), map_video_memory(), and unmap_video_memory()
- */
-#define MEM_ALLOC_THRESHOLD (1024*768*4+32)
-/* Minimum value that the pixel clock can be set to in pico seconds
- * This is determined by platform clock/3 where the minimum platform
- * clock is 533MHz. This gives 5629 pico seconds.
- */
-#define MIN_PIX_CLK 5629
-#define MAX_PIX_CLK 96096
-
 #include <linux/types.h>
 
-struct mfb_alpha {
-	int enable;
-	int alpha;
-};
-
-struct mfb_chroma_key {
-	int enable;
-	__u8  red_max;
-	__u8  green_max;
-	__u8  blue_max;
-	__u8  red_min;
-	__u8  green_min;
-	__u8  blue_min;
-};
-
-struct aoi_display_offset {
-	int x_aoi_d;
-	int y_aoi_d;
-};
-
-#define MFB_SET_CHROMA_KEY	_IOW('M', 1, struct mfb_chroma_key)
-#define MFB_SET_BRIGHTNESS	_IOW('M', 3, __u8)
-
-#define MFB_SET_ALPHA		0x80014d00
-#define MFB_GET_ALPHA		0x40014d00
-#define MFB_SET_AOID		0x80084d04
-#define MFB_GET_AOID		0x40084d04
-#define MFB_SET_PIXFMT		0x80014d08
-#define MFB_GET_PIXFMT		0x40014d08
-
-#define FBIOGET_GWINFO		0x46E0
-#define FBIOPUT_GWINFO		0x46E1
-
-#ifdef __KERNEL__
-#include <linux/spinlock.h>
-
 /*
  * These are the fields of area descriptor(in DDR memory) for every plane
  */
@@ -165,39 +118,6 @@ struct diu {
 	__be32 plut;
 } __attribute__ ((packed));
 
-struct diu_hw {
-	struct diu *diu_reg;
-	spinlock_t reg_lock;
-
-	__u32 mode;		/* DIU operation mode */
-};
-
-struct diu_addr {
-	__u8 __iomem *vaddr;	/* Virtual address */
-	dma_addr_t paddr;	/* Physical address */
-	__u32 	   offset;
-};
-
-struct diu_pool {
-	struct diu_addr ad;
-	struct diu_addr gamma;
-	struct diu_addr pallete;
-	struct diu_addr cursor;
-};
-
-#define FSL_DIU_BASE_OFFSET	0x2C000	/* Offset of DIU */
-#define INT_LCDC		64	/* DIU interrupt number */
-
-#define FSL_AOI_NUM	6	/* 5 AOIs and one dummy AOI */
-				/* 1 for plane 0, 2 for plane 1&2 each */
-
-/* Minimum X and Y resolutions */
-#define MIN_XRES	64
-#define MIN_YRES	64
-
-/* HW cursor parameters */
-#define MAX_CURS		32
-
 /* Modes of operation of DIU */
 #define MFB_MODE0	0	/* DIU off */
 #define MFB_MODE1	1	/* All three planes output to display */
@@ -205,18 +125,4 @@ struct diu_pool {
 #define MFB_MODE3	3	/* All three planes written back to memory */
 #define MFB_MODE4	4	/* Color bar generation */
 
-/* INT_STATUS/INT_MASK field descriptions */
-#define INT_VSYNC	0x01	/* Vsync interrupt  */
-#define INT_VSYNC_WB	0x02	/* Vsync interrupt for write back operation */
-#define INT_UNDRUN	0x04	/* Under run exception interrupt */
-#define INT_PARERR	0x08	/* Display parameters error interrupt */
-#define INT_LS_BF_VS	0x10	/* Lines before vsync. interrupt */
-
-/* Panels'operation modes */
-#define MFB_TYPE_OUTPUT	0	/* Panel output to display */
-#define MFB_TYPE_OFF	1	/* Panel off */
-#define MFB_TYPE_WB	2	/* Panel written back to memory */
-#define MFB_TYPE_TEST	3	/* Panel generate color bar */
-
-#endif /* __KERNEL__ */
 #endif /* __FSL_DIU_FB_H__ */
-- 
1.7.3.4



^ permalink raw reply related

* Re: [PATCH/RFC] fbdev: Add FOURCC-based format configuration API
From: Laurent Pinchart @ 2011-06-21 22:31 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: linux-fbdev, linux-media, dri-devel, FlorianSchandinat
In-Reply-To: <BANLkTim6wUaeZCya=9dMvU7iHj4W4E57Fg@mail.gmail.com>

Hi Geert,

On Tuesday 21 June 2011 22:49:14 Geert Uytterhoeven wrote:
> On Tue, Jun 21, 2011 at 17:36, Laurent Pinchart wrote:
> > +The following types and visuals are supported.
> > +
> > +- FB_TYPE_PACKED_PIXELS
> > +
> > +- FB_TYPE_PLANES
> 
> You forgot FB_TYPE_INTERLEAVED_PLANES, FB_TYPE_TEXT, and
> FB_TYPE_VGA_PLANES. Ah, that's the "feel free to extend the API doc"  :-)

To be honest, I don't know how they work. That's why I haven't documented 
them.

> > +The FOURCC-based API replaces format descriptions by four character
> > codes +(FOURCC). FOURCCs are abstract identifiers that uniquely define a
> > format +without explicitly describing it. This is the only API that
> > supports YUV +formats. Drivers are also encouraged to implement the
> > FOURCC-based API for RGB +and grayscale formats.
> > +
> > +Drivers that support the FOURCC-based API report this capability by
> > setting +the FB_CAP_FOURCC bit in the fb_fix_screeninfo capabilities
> > field. +
> > +FOURCC definitions are located in the linux/videodev2.h header. However,
> > and +despite starting with the V4L2_PIX_FMT_prefix, they are not
> > restricted to V4L2 +and don't require usage of the V4L2 subsystem.
> > FOURCC documentation is +available in
> > Documentation/DocBook/v4l/pixfmt.xml.
> > +
> > +To select a format, applications set the FB_VMODE_FOURCC bit in the
> > +fb_var_screeninfo vmode field, and set the fourcc field to the desired
> > FOURCC. +The bits_per_pixel, red, green, blue, transp and nonstd fields
> > must be set to +0 by applications and ignored by drivers. Note that the
> > grayscale and fourcc +fields share the same memory location. Application
> > must thus not set the +grayscale field to 0.
> 
> These are the only parts I don't like: (ab)using the vmode field (this
> isn't really a vmode flag), and the union of grayscale and fourcc (avoid
> unions where possible).

I've proposed adding a FB_NONSTD_FORMAT bit to the nonstd field as a FOURCC 
mode indicator in my initial RFC. Florian Tobias Schandinat wasn't very happy 
with that, and proposed using the vmode field instead.

Given that there's virtually no fbdev documentation, whether the vmode field 
and/or nonstd field are good fit for a FOURCC mode indicator is subject to 
interpretation.

> What about storing the FOURCC value in nonstd instead?

Wouldn't that be a union of nonstd and fourcc ? :-) FOURCC-based format 
setting will be a standard fbdev API, I'm not very keen on storing it in the 
nonstd field without a union.

> As FOURCC values are always 4 ASCII characters (hence all 4 bytes must
> be non-zero), I don't think there are any conflicts with existing values of
> nonstd. To make it even safer and easier to parse, you could set bit 31 of
> nonstd as a FOURCC indicator.

I would then create a union between nonstd and fourcc, and document nonstd as 
being used for the legacy API only. Most existing drivers use a couple of 
nonstd bits only. The driver that (ab)uses nonstd the most is pxafb and uses 
bits 22:0. Bits 31:24 are never used as far as I can tell, so nonstd & 
0xff000000 != 0 could be used as a FOURCC mode test.

This assumes that FOURCCs will never have their last character set to '\0'. Is 
that a safe assumption for the future ?

-- 
Regards,

Laurent Pinchart

^ permalink raw reply

* Re: [PATCH] fsl-diu-fb: remove the ioctl interface
From: Anatolij Gustschin @ 2011-06-21 22:38 UTC (permalink / raw)
  To: Timur Tabi; +Cc: linuxppc-dev, linux-fbdev, lethal, yorksun
In-Reply-To: <1308691655-3416-1-git-send-email-timur@freescale.com>

On Tue, 21 Jun 2011 16:27:35 -0500
Timur Tabi <timur@freescale.com> wrote:

> The ioctl interface in the Freescale DIU framebuffer driver is just a
> collection of miscellaneous functions which were only used in a one-time
> demo application that was never distributed.  Plus, the ioctls were spread
> across two types (both conflicting), and the demo app didn't even use all
> of them.
> 
> Removing the ioctl interface also allows us to clean up the header file and
> remove other unusued stuff.

No! We are using ioctl interface of this driver in many video
rendering applications on overlay planes on huge number of boards.
So, please don't remove it.

Anatolij

^ permalink raw reply

* Re: [PATCH] fsl-diu-fb: remove the ioctl interface
From: Tabi Timur-B04825 @ 2011-06-21 23:13 UTC (permalink / raw)
  To: Anatolij Gustschin
  Cc: sun york-R58495, linux-fbdev@vger.kernel.org, lethal@linux-sh.org,
	Tabi Timur-B04825, linuxppc-dev@ozlabs.org
In-Reply-To: <20110622003853.1041385c@wker>

Anatolij Gustschin wrote:
> No! We are using ioctl interface of this driver in many video
> rendering applications on overlay planes on huge number of boards.
> So, please don't remove it.

Ok, I had no idea anyone was using it.

Can you email me details about how you use the ioctl interface?  If I can't 
remove it, maybe I can clean it up.

-- 
Timur Tabi
Linux kernel developer at Freescale

^ permalink raw reply

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

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

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

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

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

v2: change clock name of exynos4 FIMD: "fimd" -> "lcd"
     use 'has_clksel' variable in order to distinguish FIMD version
     add 'lcd_clk' that can be used for only lcd pixel clock
     add callback 'enable_clk()' to enable parent clock 'sclk_fimd'.
v3: remove the callback from the platform data structure
v4: move clk_enable(sfb->lcd_clk) under the if statement

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

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

^ permalink raw reply

* [PATCH V4 1/5] ARM: EXYNOS4: Change clock name for FIMD
From: JinGoo Han @ 2011-06-22  3:42 UTC (permalink / raw)
  To: Kukjin Kim, Paul Mundt, linux-samsung-soc@vger.kernel.org,
	"linux-fbdev@vger.kernel.org" <linux-f>
  Cc: ANAND KUMAR N, Sylwester Nawrocki, THOMAS P ABRAHAM,
	Marek Szyprowski, Kyungmin Park, In-Ki Dae, ARM Linux, Ben Dooks,
	JinGoo Han

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

This patch changes clock name for FIMD from "fimd" to "lcd".

Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
 arch/arm/mach-exynos4/clock.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c
index 871f9d5..12e6853 100644
--- a/arch/arm/mach-exynos4/clock.c
+++ b/arch/arm/mach-exynos4/clock.c
@@ -433,12 +433,12 @@ static struct clk init_clocks_off[] = {
 		.enable		= exynos4_clk_ip_cam_ctrl,
 		.ctrlbit	= (1 << 3),
 	}, {
-		.name		= "fimd",
+		.name		= "lcd",
 		.id		= 0,
 		.enable		= exynos4_clk_ip_lcd0_ctrl,
 		.ctrlbit	= (1 << 0),
 	}, {
-		.name		= "fimd",
+		.name		= "lcd",
 		.id		= 1,
 		.enable		= exynos4_clk_ip_lcd1_ctrl,
 		.ctrlbit	= (1 << 0),
-- 
1.7.1

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

^ permalink raw reply related

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

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

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

This patch adds resource definitions for EXYNOS4 FIMD.
IRQ and SFR definitions are added.

Signed-off-by: Jonghun Han <jonghun.han@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
 arch/arm/mach-exynos4/include/mach/irqs.h |    8 ++++++++
 arch/arm/mach-exynos4/include/mach/map.h  |    5 +++++
 2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-exynos4/include/mach/irqs.h b/arch/arm/mach-exynos4/include/mach/irqs.h
index 5d03730..2cd2090 100644
--- a/arch/arm/mach-exynos4/include/mach/irqs.h
+++ b/arch/arm/mach-exynos4/include/mach/irqs.h
@@ -73,6 +73,14 @@
 #define IRQ_SYSMMU_MFC_M1_0	COMBINER_IRQ(5, 6)
 #define IRQ_SYSMMU_PCIE_0	COMBINER_IRQ(5, 7)
 
+#define IRQ_FIMD0_FIFO		COMBINER_IRQ(11, 0)
+#define IRQ_FIMD0_VSYNC		COMBINER_IRQ(11, 1)
+#define IRQ_FIMD0_SYSTEM	COMBINER_IRQ(11, 2)
+
+#define IRQ_FIMD1_FIFO		COMBINER_IRQ(12, 0)
+#define IRQ_FIMD1_VSYNC		COMBINER_IRQ(12, 1)
+#define IRQ_FIMD1_SYSTEM	COMBINER_IRQ(12, 2)
+
 #define IRQ_PDMA0		COMBINER_IRQ(21, 0)
 #define IRQ_PDMA1		COMBINER_IRQ(21, 1)
 
diff --git a/arch/arm/mach-exynos4/include/mach/map.h b/arch/arm/mach-exynos4/include/mach/map.h
index 0009e77..94006f7 100644
--- a/arch/arm/mach-exynos4/include/mach/map.h
+++ b/arch/arm/mach-exynos4/include/mach/map.h
@@ -93,6 +93,9 @@
 #define EXYNOS4_PA_MIPI_CSIS0		0x11880000
 #define EXYNOS4_PA_MIPI_CSIS1		0x11890000
 
+#define EXYNOS4_PA_FIMD0		0x11C00000
+#define EXYNOS4_PA_FIMD1		0x12000000
+
 #define EXYNOS4_PA_HSMMC(x)		(0x12510000 + ((x) * 0x10000))
 
 #define EXYNOS4_PA_SATA			0x12560000
@@ -140,6 +143,8 @@
 #define S5P_PA_FIMC3			EXYNOS4_PA_FIMC3
 #define S5P_PA_MIPI_CSIS0		EXYNOS4_PA_MIPI_CSIS0
 #define S5P_PA_MIPI_CSIS1		EXYNOS4_PA_MIPI_CSIS1
+#define S5P_PA_FIMD0			EXYNOS4_PA_FIMD0
+#define S5P_PA_FIMD1			EXYNOS4_PA_FIMD1
 #define S5P_PA_ONENAND			EXYNOS4_PA_ONENAND
 #define S5P_PA_ONENAND_DMA		EXYNOS4_PA_ONENAND_DMA
 #define S5P_PA_SDRAM			EXYNOS4_PA_SDRAM
-- 
1.7.1

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

^ permalink raw reply related

* [PATCH V4 3/5] ARM: EXYNOS4: Add platform device and helper functions
From: JinGoo Han @ 2011-06-22  3:46 UTC (permalink / raw)
  To: Kukjin Kim, Paul Mundt, linux-samsung-soc@vger.kernel.org,
	"linux-fbdev@vger.kernel.org" <linux-f>
  Cc: ANAND KUMAR N, Sylwester Nawrocki, THOMAS P ABRAHAM,
	Marek Szyprowski, Kyungmin Park, In-Ki Dae, ARM Linux, Ben Dooks,
	JinGoo Han

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

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

This patch adds platform device s5p_device_fimd0 for EXYNOS4 FIMD0.
EXYNOS4 has two FIMDs(FIMD0, FIMD1). FIMD1 will be added later.
Some definitions used to enable EXYNOS4 FIMD0 are added.

Signed-off-by: Jonghun Han <jonghun.han@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
 arch/arm/mach-exynos4/Kconfig                |    9 ++++
 arch/arm/mach-exynos4/Makefile               |    1 +
 arch/arm/mach-exynos4/cpu.c                  |    4 +-
 arch/arm/mach-exynos4/include/mach/regs-fb.h |   21 ++++++++
 arch/arm/mach-exynos4/setup-fimd0-24bpp.c    |   47 ++++++++++++++++++
 arch/arm/plat-s5p/Kconfig                    |    5 ++
 arch/arm/plat-s5p/Makefile                   |    1 +
 arch/arm/plat-s5p/dev-fimd0.c                |   67 ++++++++++++++++++++++++++
 arch/arm/plat-samsung/include/plat/devs.h    |    1 +
 arch/arm/plat-samsung/include/plat/fb-core.h |   15 ++++++
 arch/arm/plat-samsung/include/plat/fb.h      |   15 ++++++
 11 files changed, 185 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-exynos4/include/mach/regs-fb.h
 create mode 100644 arch/arm/mach-exynos4/setup-fimd0-24bpp.c
 create mode 100644 arch/arm/plat-s5p/dev-fimd0.c

diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
index 1435fc3..8428ac7 100644
--- a/arch/arm/mach-exynos4/Kconfig
+++ b/arch/arm/mach-exynos4/Kconfig
@@ -25,6 +25,11 @@ config EXYNOS4_DEV_AHCI
 	help
 	  Compile in platform device definitions for AHCI
 
+config EXYNOS4_SETUP_FIMD0_24BPP
+	bool
+	help
+	  Common setup code for FIMD0 with a 24bpp RGB display helper.
+
 config EXYNOS4_DEV_PD
 	bool
 	help
@@ -103,6 +108,7 @@ menu "EXYNOS4 Machines"
 config MACH_SMDKC210
 	bool "SMDKC210"
 	select CPU_EXYNOS4210
+	select S5P_DEV_FIMD0
 	select S3C_DEV_RTC
 	select S3C_DEV_WDT
 	select S3C_DEV_I2C1
@@ -112,6 +118,7 @@ config MACH_SMDKC210
 	select S3C_DEV_HSMMC3
 	select EXYNOS4_DEV_PD
 	select EXYNOS4_DEV_SYSMMU
+	select EXYNOS4_SETUP_FIMD0_24BPP
 	select EXYNOS4_SETUP_I2C1
 	select EXYNOS4_SETUP_SDHCI
 	help
@@ -120,6 +127,7 @@ config MACH_SMDKC210
 config MACH_SMDKV310
 	bool "SMDKV310"
 	select CPU_EXYNOS4210
+	select S5P_DEV_FIMD0
 	select S3C_DEV_RTC
 	select S3C_DEV_WDT
 	select S3C_DEV_I2C1
@@ -130,6 +138,7 @@ config MACH_SMDKV310
 	select SAMSUNG_DEV_KEYPAD
 	select EXYNOS4_DEV_PD
 	select EXYNOS4_DEV_SYSMMU
+	select EXYNOS4_SETUP_FIMD0_24BPP
 	select EXYNOS4_SETUP_I2C1
 	select EXYNOS4_SETUP_KEYPAD
 	select EXYNOS4_SETUP_SDHCI
diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile
index 60fe5ec..aa4d1f4 100644
--- a/arch/arm/mach-exynos4/Makefile
+++ b/arch/arm/mach-exynos4/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_EXYNOS4_DEV_PD)		+= dev-pd.o
 obj-$(CONFIG_EXYNOS4_DEV_SYSMMU)	+= dev-sysmmu.o
 
 obj-$(CONFIG_EXYNOS4_SETUP_FIMC)	+= setup-fimc.o
+obj-$(CONFIG_EXYNOS4_SETUP_FIMD0_24BPP)	+= setup-fimd0-24bpp.o
 obj-$(CONFIG_EXYNOS4_SETUP_I2C1)	+= setup-i2c1.o
 obj-$(CONFIG_EXYNOS4_SETUP_I2C2)	+= setup-i2c2.o
 obj-$(CONFIG_EXYNOS4_SETUP_I2C3)	+= setup-i2c3.o
diff --git a/arch/arm/mach-exynos4/cpu.c b/arch/arm/mach-exynos4/cpu.c
index 9babe44..778a5b0 100644
--- a/arch/arm/mach-exynos4/cpu.c
+++ b/arch/arm/mach-exynos4/cpu.c
@@ -19,9 +19,10 @@
 
 #include <plat/cpu.h>
 #include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/fb-core.h>
 #include <plat/exynos4.h>
 #include <plat/sdhci.h>
-#include <plat/devs.h>
 #include <plat/fimc-core.h>
 
 #include <mach/regs-irq.h>
@@ -132,6 +133,7 @@ void __init exynos4_map_io(void)
 	s3c_fimc_setname(1, "exynos4-fimc");
 	s3c_fimc_setname(2, "exynos4-fimc");
 	s3c_fimc_setname(3, "exynos4-fimc");
+	s5p_fb_setname(0, "exynos4-fb");	/* FIMD0 */
 }
 
 void __init exynos4_init_clocks(int xtal)
diff --git a/arch/arm/mach-exynos4/include/mach/regs-fb.h b/arch/arm/mach-exynos4/include/mach/regs-fb.h
new file mode 100644
index 0000000..f320105
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/regs-fb.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2010 Ben Dooks <ben-linux@fluff.org>
+ *
+ * Dummy framebuffer to allow build for the moment.
+ *
+ * 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.
+*/
+
+#ifndef __ASM_ARCH_MACH_REGS_FB_H
+#define __ASM_ARCH_MACH_REGS_FB_H __FILE__
+
+#include <plat/regs-fb-v4.h>
+
+static inline unsigned int s3c_fb_pal_reg(unsigned int window, int reg)
+{
+	return 0x2400 + (window * 256 * 4) + reg;
+}
+
+#endif /* __ASM_ARCH_MACH_REGS_FB_H */
diff --git a/arch/arm/mach-exynos4/setup-fimd0-24bpp.c b/arch/arm/mach-exynos4/setup-fimd0-24bpp.c
new file mode 100644
index 0000000..3ca8555
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-fimd0-24bpp.c
@@ -0,0 +1,47 @@
+/* linux/arch/arm/mach-exynos4/setup-fimd0-24bpp.c
+ *
+ * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Base Exynos4 setup information for 24bpp LCD framebuffer
+ *
+ * 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.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+
+#include <plat/fb.h>
+#include <plat/gpio-cfg.h>
+
+#include <mach/regs-clock.h>
+#include <mach/regs-fb.h>
+#include <mach/map.h>
+
+void exynos4_fimd0_gpio_setup_24bpp(void)
+{
+	unsigned int reg = 0;
+
+	s3c_gpio_cfgrange_nopull(EXYNOS4_GPF0(0), 8, S3C_GPIO_SFN(2));
+	s3c_gpio_cfgrange_nopull(EXYNOS4_GPF1(0), 8, S3C_GPIO_SFN(2));
+	s3c_gpio_cfgrange_nopull(EXYNOS4_GPF2(0), 8, S3C_GPIO_SFN(2));
+	s3c_gpio_cfgrange_nopull(EXYNOS4_GPF3(0), 4, S3C_GPIO_SFN(2));
+
+	/*
+	 * Set DISPLAY_CONTROL register for Display path selection.
+	 *
+	 * DISPLAY_CONTROL[1:0]
+	 * ---------------------
+	 *  00 | MIE
+	 *  01 | MDINE
+	 *  10 | FIMD : selected
+	 *  11 | FIMD
+	 */
+	reg = __raw_readl(S3C_VA_SYS + 0x0210);
+	reg |= (1 << 1);
+	__raw_writel(reg, S3C_VA_SYS + 0x0210);
+}
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
index e98f5c5..46de16e 100644
--- a/arch/arm/plat-s5p/Kconfig
+++ b/arch/arm/plat-s5p/Kconfig
@@ -70,6 +70,11 @@ config S5P_DEV_FIMC3
 	help
 	  Compile in platform device definitions for FIMC controller 3
 
+config S5P_DEV_FIMD0
+	bool
+	help
+	  Compile in platform device definitions for FIMD controller 0
+
 config S5P_DEV_ONENAND
 	bool
 	help
diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
index e234cc4..eec7e24 100644
--- a/arch/arm/plat-s5p/Makefile
+++ b/arch/arm/plat-s5p/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_S5P_DEV_FIMC0)	+= dev-fimc0.o
 obj-$(CONFIG_S5P_DEV_FIMC1)	+= dev-fimc1.o
 obj-$(CONFIG_S5P_DEV_FIMC2)	+= dev-fimc2.o
 obj-$(CONFIG_S5P_DEV_FIMC3)	+= dev-fimc3.o
+obj-$(CONFIG_S5P_DEV_FIMD0)	+= dev-fimd0.o
 obj-$(CONFIG_S5P_DEV_ONENAND)	+= dev-onenand.o
 obj-$(CONFIG_S5P_DEV_CSIS0)	+= dev-csis0.o
 obj-$(CONFIG_S5P_DEV_CSIS1)	+= dev-csis1.o
diff --git a/arch/arm/plat-s5p/dev-fimd0.c b/arch/arm/plat-s5p/dev-fimd0.c
new file mode 100644
index 0000000..9e7176c
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-fimd0.c
@@ -0,0 +1,67 @@
+/* linux/arch/arm/plat-s5p/dev-fimd0.c
+ *
+ * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Core file for Samsung Display Controller (FIMD) driver
+ *
+ * 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.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/gfp.h>
+#include <linux/dma-mapping.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/fb.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s5p_fimd0_resource[] = {
+	[0] = {
+		.start  = S5P_PA_FIMD0,
+		.end    = S5P_PA_FIMD0 + SZ_32K - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = IRQ_FIMD0_VSYNC,
+		.end    = IRQ_FIMD0_VSYNC,
+		.flags  = IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start  = IRQ_FIMD0_FIFO,
+		.end    = IRQ_FIMD0_FIFO,
+		.flags  = IORESOURCE_IRQ,
+	},
+	[3] = {
+		.start  = IRQ_FIMD0_SYSTEM,
+		.end    = IRQ_FIMD0_SYSTEM,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static u64 fimd0_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s5p_device_fimd0 = {
+	.name           = "s5p-fb",
+	.id             = 0,
+	.num_resources  = ARRAY_SIZE(s5p_fimd0_resource),
+	.resource       = s5p_fimd0_resource,
+	.dev            = {
+		.dma_mask               = &fimd0_dmamask,
+		.coherent_dma_mask      = DMA_BIT_MASK(32),
+	},
+};
+
+void __init s5p_fimd0_set_platdata(struct s3c_fb_platdata *pd)
+{
+	s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata),
+			&s5p_device_fimd0);
+}
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 4af108f..370bd2b 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -45,6 +45,7 @@ extern struct platform_device s3c64xx_device_ac97;
 extern struct platform_device s3c_device_ts;
 
 extern struct platform_device s3c_device_fb;
+extern struct platform_device s5p_device_fimd0;
 extern struct platform_device s3c_device_ohci;
 extern struct platform_device s3c_device_lcd;
 extern struct platform_device s3c_device_wdt;
diff --git a/arch/arm/plat-samsung/include/plat/fb-core.h b/arch/arm/plat-samsung/include/plat/fb-core.h
index bca383e..6abcbf1 100644
--- a/arch/arm/plat-samsung/include/plat/fb-core.h
+++ b/arch/arm/plat-samsung/include/plat/fb-core.h
@@ -26,4 +26,19 @@ static inline void s3c_fb_setname(char *name)
 #endif
 }
 
+/* Re-define device name depending on support. */
+static inline void s5p_fb_setname(int id, char *name)
+{
+	switch (id) {
+#ifdef CONFIG_S5P_DEV_FIMD0
+	case 0:
+		s5p_device_fimd0.name = name;
+	break;
+#endif
+	default:
+		printk(KERN_ERR "%s: invalid device id(%d)\n", __func__, id);
+	break;
+	}
+}
+
 #endif /* __ASM_PLAT_FB_CORE_H */
diff --git a/arch/arm/plat-samsung/include/plat/fb.h b/arch/arm/plat-samsung/include/plat/fb.h
index cb3ca3a..01f10e4 100644
--- a/arch/arm/plat-samsung/include/plat/fb.h
+++ b/arch/arm/plat-samsung/include/plat/fb.h
@@ -74,6 +74,14 @@ struct s3c_fb_platdata {
 extern void s3c_fb_set_platdata(struct s3c_fb_platdata *pd);
 
 /**
+ * s5p_fimd0_set_platdata() - Setup the FB device with platform data.
+ * @pd: The platform data to set. The data is copied from the passed structure
+ *      so the machine data can mark the data __initdata so that any unused
+ *      machines will end up dumping their data at runtime.
+ */
+extern void s5p_fimd0_set_platdata(struct s3c_fb_platdata *pd);
+
+/**
  * s3c64xx_fb_gpio_setup_24bpp() - S3C64XX setup function for 24bpp LCD
  *
  * Initialise the GPIO for an 24bpp LCD display on the RGB interface.
@@ -94,4 +102,11 @@ extern void s5pc100_fb_gpio_setup_24bpp(void);
  */
 extern void s5pv210_fb_gpio_setup_24bpp(void);
 
+/**
+ * exynos4_fimd0_gpio_setup_24bpp() - Exynos4 setup function for 24bpp LCD0
+ *
+ * Initialise the GPIO for an 24bpp LCD display on the RGB interface 0.
+ */
+extern void exynos4_fimd0_gpio_setup_24bpp(void);
+
 #endif /* __PLAT_S3C_FB_H */
-- 
1.7.1

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

^ permalink raw reply related

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

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

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

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

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

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

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

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

^ permalink raw reply related

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

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

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

This patch adds support EXYNOS4 FIMD0 and LTE480WV LCD pannel.

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

diff --git a/arch/arm/mach-exynos4/mach-smdkc210.c b/arch/arm/mach-exynos4/mach-smdkc210.c
index e645f7a..360a50a 100644
--- a/arch/arm/mach-exynos4/mach-smdkc210.c
+++ b/arch/arm/mach-exynos4/mach-smdkc210.c
@@ -9,26 +9,33 @@
 */
 
 #include <linux/serial_core.h>
+#include <linux/delay.h>
 #include <linux/gpio.h>
+#include <linux/lcd.h>
 #include <linux/mmc/host.h>
 #include <linux/platform_device.h>
 #include <linux/smsc911x.h>
 #include <linux/io.h>
 #include <linux/i2c.h>
+#include <linux/clk.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 
+#include <video/platform_lcd.h>
+
 #include <plat/regs-serial.h>
 #include <plat/regs-srom.h>
 #include <plat/exynos4.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
+#include <plat/fb.h>
 #include <plat/sdhci.h>
 #include <plat/iic.h>
 #include <plat/pd.h>
 
 #include <mach/map.h>
+#include <mach/regs-fb.h>
 
 /* Following are default values for UCON, ULCON and UFCON UART registers */
 #define SMDKC210_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
@@ -111,6 +118,69 @@ static struct s3c_sdhci_platdata smdkc210_hsmmc3_pdata __initdata = {
 	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
 };
 
+static void lcd_lte480wv_set_power(struct plat_lcd_data *pd,
+				   unsigned int power)
+{
+	if (power) {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+		gpio_request(EXYNOS4_GPD0(1), "GPD0");
+		gpio_direction_output(EXYNOS4_GPD0(1), 1);
+		gpio_free(EXYNOS4_GPD0(1));
+#endif
+		/* fire nRESET on power up */
+		gpio_request(EXYNOS4_GPX0(6), "GPX0");
+
+		gpio_direction_output(EXYNOS4_GPX0(6), 1);
+		mdelay(100);
+
+		gpio_set_value(EXYNOS4_GPX0(6), 0);
+		mdelay(10);
+
+		gpio_set_value(EXYNOS4_GPX0(6), 1);
+		mdelay(10);
+
+		gpio_free(EXYNOS4_GPX0(6));
+	} else {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+		gpio_request(EXYNOS4_GPD0(1), "GPD0");
+		gpio_direction_output(EXYNOS4_GPD0(1), 0);
+		gpio_free(EXYNOS4_GPD0(1));
+#endif
+	}
+}
+
+static struct plat_lcd_data smdkc210_lcd_lte480wv_data = {
+	.set_power      = lcd_lte480wv_set_power,
+};
+
+static struct platform_device smdkc210_lcd_lte480wv = {
+	.name                   = "platform-lcd",
+	.dev.parent             = &s5p_device_fimd0.dev,
+	.dev.platform_data      = &smdkc210_lcd_lte480wv_data,
+};
+
+static struct s3c_fb_pd_win smdkc210_fb_win0 = {
+	.win_mode = {
+		.left_margin    = 13,
+		.right_margin   = 8,
+		.upper_margin   = 7,
+		.lower_margin   = 5,
+		.hsync_len      = 3,
+		.vsync_len      = 1,
+		.xres   = 800,
+		.yres   = 480,
+	},
+	.max_bpp        = 32,
+	.default_bpp    = 24,
+};
+
+static struct s3c_fb_platdata smdkc210_lcd0_pdata __initdata = {
+	.win[0]		= &smdkc210_fb_win0,
+	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+	.vidcon1	= VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+	.setup_gpio	= exynos4_fimd0_gpio_setup_24bpp,
+};
+
 static struct resource smdkc210_smsc911x_resources[] = {
 	[0] = {
 		.start	= EXYNOS4_PA_SROM_BANK(1),
@@ -165,6 +235,8 @@ static struct platform_device *smdkc210_devices[] __initdata = {
 	&exynos4_device_pd[PD_GPS],
 	&exynos4_device_sysmmu,
 	&samsung_asoc_dma,
+	&s5p_device_fimd0,
+	&smdkc210_lcd_lte480wv,
 	&smdkc210_smsc911x,
 };
 
@@ -191,6 +263,44 @@ static void __init smdkc210_smsc911x_init(void)
 		     (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
 }
 
+static int __init smdkc210_fimd0_setup_clock(void)
+{
+	struct clk *sclk = NULL;
+	struct clk *mout_mpll = NULL;
+
+	u32 rate = 0;
+
+	sclk = clk_get(&s5p_device_fimd0.dev, "sclk_fimd");
+	if (IS_ERR(sclk)) {
+		printk(KERN_ERR "failed to get sclk for fimd\n");
+		goto err_clk2;
+	}
+
+	mout_mpll = clk_get(NULL, "mout_mpll");
+	if (IS_ERR(mout_mpll)) {
+		printk(KERN_ERR "failed to get mout_mpll\n");
+		goto err_clk1;
+	}
+
+	clk_set_parent(sclk, mout_mpll);
+	if (!rate)
+		rate = 134000000;
+
+	clk_set_rate(sclk, rate);
+
+	clk_put(sclk);
+	clk_put(mout_mpll);
+
+	return 0;
+
+err_clk1:
+	clk_put(mout_mpll);
+err_clk2:
+	clk_put(sclk);
+
+	return -EINVAL;
+}
+
 static void __init smdkc210_map_io(void)
 {
 	s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -210,7 +320,11 @@ static void __init smdkc210_machine_init(void)
 	s3c_sdhci2_set_platdata(&smdkc210_hsmmc2_pdata);
 	s3c_sdhci3_set_platdata(&smdkc210_hsmmc3_pdata);
 
+	s5p_fimd0_set_platdata(&smdkc210_lcd0_pdata);
+
 	platform_add_devices(smdkc210_devices, ARRAY_SIZE(smdkc210_devices));
+
+	smdkc210_fimd0_setup_clock();
 }
 
 MACHINE_START(SMDKC210, "SMDKC210")
diff --git a/arch/arm/mach-exynos4/mach-smdkv310.c b/arch/arm/mach-exynos4/mach-smdkv310.c
index 1526764..7bc12b5 100644
--- a/arch/arm/mach-exynos4/mach-smdkv310.c
+++ b/arch/arm/mach-exynos4/mach-smdkv310.c
@@ -9,28 +9,35 @@
 */
 
 #include <linux/serial_core.h>
+#include <linux/delay.h>
 #include <linux/gpio.h>
+#include <linux/lcd.h>
 #include <linux/mmc/host.h>
 #include <linux/platform_device.h>
 #include <linux/smsc911x.h>
 #include <linux/io.h>
 #include <linux/i2c.h>
 #include <linux/input.h>
+#include <linux/clk.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 
+#include <video/platform_lcd.h>
+
 #include <plat/regs-serial.h>
 #include <plat/regs-srom.h>
 #include <plat/exynos4.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
+#include <plat/fb.h>
 #include <plat/keypad.h>
 #include <plat/sdhci.h>
 #include <plat/iic.h>
 #include <plat/pd.h>
 
 #include <mach/map.h>
+#include <mach/regs-fb.h>
 
 /* Following are default values for UCON, ULCON and UFCON UART registers */
 #define SMDKV310_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
@@ -113,6 +120,69 @@ static struct s3c_sdhci_platdata smdkv310_hsmmc3_pdata __initdata = {
 	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
 };
 
+static void lcd_lte480wv_set_power(struct plat_lcd_data *pd,
+				   unsigned int power)
+{
+	if (power) {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+		gpio_request(EXYNOS4_GPD0(1), "GPD0");
+		gpio_direction_output(EXYNOS4_GPD0(1), 1);
+		gpio_free(EXYNOS4_GPD0(1));
+#endif
+		/* fire nRESET on power up */
+		gpio_request(EXYNOS4_GPX0(6), "GPX0");
+
+		gpio_direction_output(EXYNOS4_GPX0(6), 1);
+		mdelay(100);
+
+		gpio_set_value(EXYNOS4_GPX0(6), 0);
+		mdelay(10);
+
+		gpio_set_value(EXYNOS4_GPX0(6), 1);
+		mdelay(10);
+
+		gpio_free(EXYNOS4_GPX0(6));
+	} else {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+		gpio_request(EXYNOS4_GPD0(1), "GPD0");
+		gpio_direction_output(EXYNOS4_GPD0(1), 0);
+		gpio_free(EXYNOS4_GPD0(1));
+#endif
+	}
+}
+
+static struct plat_lcd_data smdkv310_lcd_lte480wv_data = {
+	.set_power      = lcd_lte480wv_set_power,
+};
+
+static struct platform_device smdkv310_lcd_lte480wv = {
+	.name                   = "platform-lcd",
+	.dev.parent             = &s5p_device_fimd0.dev,
+	.dev.platform_data      = &smdkv310_lcd_lte480wv_data,
+};
+
+static struct s3c_fb_pd_win smdkv310_fb_win0 = {
+	.win_mode = {
+		.left_margin    = 13,
+		.right_margin   = 8,
+		.upper_margin   = 7,
+		.lower_margin   = 5,
+		.hsync_len      = 3,
+		.vsync_len      = 1,
+		.xres   = 800,
+		.yres   = 480,
+	},
+	.max_bpp        = 32,
+	.default_bpp    = 24,
+};
+
+static struct s3c_fb_platdata smdkv310_lcd0_pdata __initdata = {
+	.win[0]		= &smdkv310_fb_win0,
+	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+	.vidcon1	= VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+	.setup_gpio	= exynos4_fimd0_gpio_setup_24bpp,
+};
+
 static struct resource smdkv310_smsc911x_resources[] = {
 	[0] = {
 		.start	= EXYNOS4_PA_SROM_BANK(1),
@@ -187,6 +257,8 @@ static struct platform_device *smdkv310_devices[] __initdata = {
 	&exynos4_device_pd[PD_GPS],
 	&exynos4_device_sysmmu,
 	&samsung_asoc_dma,
+	&s5p_device_fimd0,
+	&smdkv310_lcd_lte480wv,
 	&smdkv310_smsc911x,
 };
 
@@ -213,6 +285,44 @@ static void __init smdkv310_smsc911x_init(void)
 		     (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
 }
 
+static int __init smdkv310_fimd0_setup_clock(void)
+{
+	struct clk *sclk = NULL;
+	struct clk *mout_mpll = NULL;
+
+	u32 rate = 0;
+
+	sclk = clk_get(&s5p_device_fimd0.dev, "sclk_fimd");
+	if (IS_ERR(sclk)) {
+		printk(KERN_ERR "failed to get sclk for fimd\n");
+		goto err_clk2;
+	}
+
+	mout_mpll = clk_get(NULL, "mout_mpll");
+	if (IS_ERR(mout_mpll)) {
+		printk(KERN_ERR "failed to get mout_mpll\n");
+		goto err_clk1;
+	}
+
+	clk_set_parent(sclk, mout_mpll);
+	if (!rate)
+		rate = 134000000;
+
+	clk_set_rate(sclk, rate);
+
+	clk_put(sclk);
+	clk_put(mout_mpll);
+
+	return 0;
+
+err_clk1:
+	clk_put(mout_mpll);
+err_clk2:
+	clk_put(sclk);
+
+	return -EINVAL;
+}
+
 static void __init smdkv310_map_io(void)
 {
 	s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -232,9 +342,13 @@ static void __init smdkv310_machine_init(void)
 	s3c_sdhci2_set_platdata(&smdkv310_hsmmc2_pdata);
 	s3c_sdhci3_set_platdata(&smdkv310_hsmmc3_pdata);
 
+	s5p_fimd0_set_platdata(&smdkv310_lcd0_pdata);
+
 	samsung_keypad_set_platdata(&smdkv310_keypad_data);
 
 	platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices));
+
+	smdkv310_fimd0_setup_clock();
 }
 
 MACHINE_START(SMDKV310, "SMDKV310")
-- 
1.7.1

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

^ permalink raw reply related

* Some questions about DRM(Direct Rendering Manager)
From: daeinki @ 2011-06-22  4:26 UTC (permalink / raw)
  To: linux-arm-kernel

Hi all,

I'm writing Samsung SoC based DRM framework and this one includes FIMD
and HDMI driver as hardware dependent modules. and for now, encoder,
connector, crtc and fb module has been materialized almost. but I'm
contending with  framebuffer setting issue(created fb_info should be
registered to linux framebuffer through register_framebuffer() or not)as
default framebuffer at booting time.

at drm_fb_helper_single_fb_probe() of drm_fb_helper.c file, fb_helper's
fb_probe callback is called and this one creates new framebuffer and
returns a value more then 0 if true. internally, this process creates an
fb_info object and drm_framebuffer and then drm_framebuffer would be
added to mode_config.fb_list of the drm_device.

a value returned, new_fb is used to decide that it calls
register_framebuffer() or drm_fb_helper_set_par(). at this point, I am
confused it's a good way to call register_framebuffer() otherwise
drm_fb_helper_set_par(). if register_framebuffer() is called then I
guess drm_fb_helper_set_par() or drm_crtc_helper_set_config() should be
called somewhere subsequently to apply this one to real hardware because
previous process is just for maintaining data logically.(not set up data
to h/w)

it's a right way to call register_framebuffer() and then
drm_fb_helper_set_par() or drm_crtc_helper_set_config()? otherwise just
only drm_fb_helper_set_par() or drm_crtc_helper_set_config() ignoring
register_framebuffer()? and what is the purpose of using
register_framebuffer()?

In my case, first, register_framebuffer() is called and then if desired
default crtc id is matched with drm_fb_helper->crtc_info[0 ~ n].crtc_id,
it gets mode_set of drm_fb_helper->crtc_info[n] and then  it calls
drm_crtc_helper_set_config(mode_set). at this time, all the hardware
configurations would be completed.

thank you in advance.

Best Regards
Inki Dae.

^ permalink raw reply

* Re: [PATCH/RFC] fbdev: Add FOURCC-based format configuration API
From: Florian Tobias Schandinat @ 2011-06-22  5:45 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: Geert Uytterhoeven, linux-fbdev, linux-media, dri-devel
In-Reply-To: <201106220031.57972.laurent.pinchart@ideasonboard.com>

Hi Geert, Laurent,

On 06/21/2011 10:31 PM, Laurent Pinchart wrote:
> Hi Geert,
>
> On Tuesday 21 June 2011 22:49:14 Geert Uytterhoeven wrote:
>> On Tue, Jun 21, 2011 at 17:36, Laurent Pinchart wrote:
>>> +The FOURCC-based API replaces format descriptions by four character
>>> codes +(FOURCC). FOURCCs are abstract identifiers that uniquely define a
>>> format +without explicitly describing it. This is the only API that
>>> supports YUV +formats. Drivers are also encouraged to implement the
>>> FOURCC-based API for RGB +and grayscale formats.
>>> +
>>> +Drivers that support the FOURCC-based API report this capability by
>>> setting +the FB_CAP_FOURCC bit in the fb_fix_screeninfo capabilities
>>> field. +
>>> +FOURCC definitions are located in the linux/videodev2.h header. However,
>>> and +despite starting with the V4L2_PIX_FMT_prefix, they are not
>>> restricted to V4L2 +and don't require usage of the V4L2 subsystem.
>>> FOURCC documentation is +available in
>>> Documentation/DocBook/v4l/pixfmt.xml.
>>> +
>>> +To select a format, applications set the FB_VMODE_FOURCC bit in the
>>> +fb_var_screeninfo vmode field, and set the fourcc field to the desired
>>> FOURCC. +The bits_per_pixel, red, green, blue, transp and nonstd fields
>>> must be set to +0 by applications and ignored by drivers. Note that the
>>> grayscale and fourcc +fields share the same memory location. Application
>>> must thus not set the +grayscale field to 0.
>>
>> These are the only parts I don't like: (ab)using the vmode field (this
>> isn't really a vmode flag), and the union of grayscale and fourcc (avoid
>> unions where possible).
>
> I've proposed adding a FB_NONSTD_FORMAT bit to the nonstd field as a FOURCC
> mode indicator in my initial RFC. Florian Tobias Schandinat wasn't very happy
> with that, and proposed using the vmode field instead.
>
> Given that there's virtually no fbdev documentation, whether the vmode field
> and/or nonstd field are good fit for a FOURCC mode indicator is subject to
> interpretation.

The reason for my suggestion is that the vmode field is accepted to contain only 
flags and at least to me there is no hard line what is part of the video mode 
and what is not. In contrast the nonstd field is already used in a lot of 
different (incompatible) ways. I think if we only use the nonstd field for 
handling FOURCC it is likely that some problems will appear.

>> What about storing the FOURCC value in nonstd instead?
>
> Wouldn't that be a union of nonstd and fourcc ? :-) FOURCC-based format
> setting will be a standard fbdev API, I'm not very keen on storing it in the
> nonstd field without a union.
>
>> As FOURCC values are always 4 ASCII characters (hence all 4 bytes must
>> be non-zero), I don't think there are any conflicts with existing values of
>> nonstd. To make it even safer and easier to parse, you could set bit 31 of
>> nonstd as a FOURCC indicator.
>
> I would then create a union between nonstd and fourcc, and document nonstd as
> being used for the legacy API only. Most existing drivers use a couple of
> nonstd bits only. The driver that (ab)uses nonstd the most is pxafb and uses
> bits 22:0. Bits 31:24 are never used as far as I can tell, so nonstd&
> 0xff000000 != 0 could be used as a FOURCC mode test.
>
> This assumes that FOURCCs will never have their last character set to '\0'. Is
> that a safe assumption for the future ?

Yes, I think. The information I found indicates that space should be used for 
padding, so a \0 shouldn't exist.
I think using only the nonstd field and requiring applications to check the 
capabilities would be possible, although not fool proof ;)

Great work, Laurent, do you have plans to modify fbset to allow using this 
format API from the command line?


Regards,

Florian Tobias Schandinat

^ permalink raw reply

* Re: Some questions about DRM(Direct Rendering Manager)
From: daeinki @ 2011-06-22  6:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4E016EDC.30200@samsung.com>

below is additional comments.

daeinki ¾´ ±Û:
> Hi all,
> 
> I'm writing Samsung SoC based DRM framework and this one includes FIMD
> and HDMI driver as hardware dependent modules. and for now, encoder,
> connector, crtc and fb module has been materialized almost. but I'm
> contending with  framebuffer setting issue(created fb_info should be
> registered to linux framebuffer through register_framebuffer() or not)as
> default framebuffer at booting time.
> 
> at drm_fb_helper_single_fb_probe() of drm_fb_helper.c file, fb_helper's
> fb_probe callback is called and this one creates new framebuffer and
> returns a value more then 0 if true. internally, this process creates an
> fb_info object and drm_framebuffer and then drm_framebuffer would be
> added to mode_config.fb_list of the drm_device.
>
it's my mistake. return value is 0 if true, nonzero otherwise.

> a value returned, new_fb is used to decide that it calls
> register_framebuffer() or drm_fb_helper_set_par(). at this point, I am
> confused it's a good way to call register_framebuffer() otherwise
> drm_fb_helper_set_par(). if register_framebuffer() is called then I
> guess drm_fb_helper_set_par() or drm_crtc_helper_set_config() should be
> called somewhere subsequently to apply this one to real hardware because
> previous process is just for maintaining data logically.(not set up data
> to h/w)
> 
> it's a right way to call register_framebuffer() and then
> drm_fb_helper_set_par() or drm_crtc_helper_set_config()? otherwise just
> only drm_fb_helper_set_par() or drm_crtc_helper_set_config() ignoring
> register_framebuffer()? and what is the purpose of using
> register_framebuffer()?
> 
I understood that if fb_probe() callback is fail then fb_info object is
registered to linux framebuffer through register_framebuffer()
otherwise(if true) hardware configuration would be completed by
drm_fb_helper_set_par() so the reason of using register_framebuffer() is
that the case of failing fb_probe() callback, it is for drawing on only
linux framebuffer. is it right?

> In my case, first, register_framebuffer() is called and then if desired
> default crtc id is matched with drm_fb_helper->crtc_info[0 ~ n].crtc_id,
> it gets mode_set of drm_fb_helper->crtc_info[n] and then  it calls
> drm_crtc_helper_set_config(mode_set). at this time, all the hardware
> configurations would be completed.
> 
> thank you in advance.
> 
> Best Regards
> Inki Dae.
> 


^ permalink raw reply

* [PATCH V5 1/5] ARM: EXYNOS4: Change clock name for FIMD
From: Jingoo Han @ 2011-06-22  6:41 UTC (permalink / raw)
  To: Kukjin Kim, Paul Mundt, linux-samsung-soc, linux-fbdev,
	Jonghun Han
  Cc: Anand Kumar N, Thomas Abraham, Sylwester Nawrocki,
	Marek Szyprowski, Kyungmin Park, Inki Dae, ARM Linux, Ben Dooks,
	Jingoo Han

This patch changes clock name for FIMD from "fimd" to "lcd".

Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
 arch/arm/mach-exynos4/clock.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c
index 871f9d5..12e6853 100644
--- a/arch/arm/mach-exynos4/clock.c
+++ b/arch/arm/mach-exynos4/clock.c
@@ -433,12 +433,12 @@ static struct clk init_clocks_off[] = {
 		.enable		= exynos4_clk_ip_cam_ctrl,
 		.ctrlbit	= (1 << 3),
 	}, {
-		.name		= "fimd",
+		.name		= "lcd",
 		.id		= 0,
 		.enable		= exynos4_clk_ip_lcd0_ctrl,
 		.ctrlbit	= (1 << 0),
 	}, {
-		.name		= "fimd",
+		.name		= "lcd",
 		.id		= 1,
 		.enable		= exynos4_clk_ip_lcd1_ctrl,
 		.ctrlbit	= (1 << 0),
-- 
1.7.1


^ permalink raw reply related

* [PATCH V5 2/5] ARM: EXYNOS4: Add FIMD resource definition
From: Jingoo Han @ 2011-06-22  6:41 UTC (permalink / raw)
  To: Kukjin Kim, Paul Mundt, linux-samsung-soc, linux-fbdev
  Cc: Anand Kumar N, Thomas Abraham, Sylwester Nawrocki,
	Marek Szyprowski, Kyungmin Park, Inki Dae, ARM Linux, Ben Dooks,
	Jonghun Han, Jingoo Han

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

This patch adds resource definitions for EXYNOS4 FIMD.
IRQ and SFR definitions are added.

Signed-off-by: Jonghun Han <jonghun.han@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
 arch/arm/mach-exynos4/include/mach/irqs.h |    8 ++++++++
 arch/arm/mach-exynos4/include/mach/map.h  |    5 +++++
 2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-exynos4/include/mach/irqs.h b/arch/arm/mach-exynos4/include/mach/irqs.h
index 5d03730..2cd2090 100644
--- a/arch/arm/mach-exynos4/include/mach/irqs.h
+++ b/arch/arm/mach-exynos4/include/mach/irqs.h
@@ -73,6 +73,14 @@
 #define IRQ_SYSMMU_MFC_M1_0	COMBINER_IRQ(5, 6)
 #define IRQ_SYSMMU_PCIE_0	COMBINER_IRQ(5, 7)
 
+#define IRQ_FIMD0_FIFO		COMBINER_IRQ(11, 0)
+#define IRQ_FIMD0_VSYNC		COMBINER_IRQ(11, 1)
+#define IRQ_FIMD0_SYSTEM	COMBINER_IRQ(11, 2)
+
+#define IRQ_FIMD1_FIFO		COMBINER_IRQ(12, 0)
+#define IRQ_FIMD1_VSYNC		COMBINER_IRQ(12, 1)
+#define IRQ_FIMD1_SYSTEM	COMBINER_IRQ(12, 2)
+
 #define IRQ_PDMA0		COMBINER_IRQ(21, 0)
 #define IRQ_PDMA1		COMBINER_IRQ(21, 1)
 
diff --git a/arch/arm/mach-exynos4/include/mach/map.h b/arch/arm/mach-exynos4/include/mach/map.h
index 0009e77..94006f7 100644
--- a/arch/arm/mach-exynos4/include/mach/map.h
+++ b/arch/arm/mach-exynos4/include/mach/map.h
@@ -93,6 +93,9 @@
 #define EXYNOS4_PA_MIPI_CSIS0		0x11880000
 #define EXYNOS4_PA_MIPI_CSIS1		0x11890000
 
+#define EXYNOS4_PA_FIMD0		0x11C00000
+#define EXYNOS4_PA_FIMD1		0x12000000
+
 #define EXYNOS4_PA_HSMMC(x)		(0x12510000 + ((x) * 0x10000))
 
 #define EXYNOS4_PA_SATA			0x12560000
@@ -140,6 +143,8 @@
 #define S5P_PA_FIMC3			EXYNOS4_PA_FIMC3
 #define S5P_PA_MIPI_CSIS0		EXYNOS4_PA_MIPI_CSIS0
 #define S5P_PA_MIPI_CSIS1		EXYNOS4_PA_MIPI_CSIS1
+#define S5P_PA_FIMD0			EXYNOS4_PA_FIMD0
+#define S5P_PA_FIMD1			EXYNOS4_PA_FIMD1
 #define S5P_PA_ONENAND			EXYNOS4_PA_ONENAND
 #define S5P_PA_ONENAND_DMA		EXYNOS4_PA_ONENAND_DMA
 #define S5P_PA_SDRAM			EXYNOS4_PA_SDRAM
-- 
1.7.1


^ permalink raw reply related

* [PATCH V5 3/5] ARM: EXYNOS4: Add platform device and helper functions for FIMD
From: Jingoo Han @ 2011-06-22  6:41 UTC (permalink / raw)
  To: Kukjin Kim, Paul Mundt, linux-samsung-soc, linux-fbdev
  Cc: Anand Kumar N, Thomas Abraham, Sylwester Nawrocki,
	Marek Szyprowski, Kyungmin Park, Inki Dae, ARM Linux, Ben Dooks,
	Jonghun Han, Jingoo Han

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

This patch adds platform device s5p_device_fimd0 for EXYNOS4 FIMD0.
EXYNOS4 has two FIMDs(FIMD0, FIMD1). FIMD1 will be added later.
Some definitions used to enable EXYNOS4 FIMD0 are added.

Signed-off-by: Jonghun Han <jonghun.han@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
 arch/arm/mach-exynos4/Kconfig                |    9 ++++
 arch/arm/mach-exynos4/Makefile               |    1 +
 arch/arm/mach-exynos4/cpu.c                  |    4 +-
 arch/arm/mach-exynos4/include/mach/regs-fb.h |   21 ++++++++
 arch/arm/mach-exynos4/setup-fimd0-24bpp.c    |   47 ++++++++++++++++++
 arch/arm/plat-s5p/Kconfig                    |    5 ++
 arch/arm/plat-s5p/Makefile                   |    1 +
 arch/arm/plat-s5p/dev-fimd0.c                |   67 ++++++++++++++++++++++++++
 arch/arm/plat-samsung/include/plat/devs.h    |    1 +
 arch/arm/plat-samsung/include/plat/fb-core.h |   15 ++++++
 arch/arm/plat-samsung/include/plat/fb.h      |   15 ++++++
 11 files changed, 185 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-exynos4/include/mach/regs-fb.h
 create mode 100644 arch/arm/mach-exynos4/setup-fimd0-24bpp.c
 create mode 100644 arch/arm/plat-s5p/dev-fimd0.c

diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
index 1435fc3..8428ac7 100644
--- a/arch/arm/mach-exynos4/Kconfig
+++ b/arch/arm/mach-exynos4/Kconfig
@@ -25,6 +25,11 @@ config EXYNOS4_DEV_AHCI
 	help
 	  Compile in platform device definitions for AHCI
 
+config EXYNOS4_SETUP_FIMD0_24BPP
+	bool
+	help
+	  Common setup code for FIMD0 with a 24bpp RGB display helper.
+
 config EXYNOS4_DEV_PD
 	bool
 	help
@@ -103,6 +108,7 @@ menu "EXYNOS4 Machines"
 config MACH_SMDKC210
 	bool "SMDKC210"
 	select CPU_EXYNOS4210
+	select S5P_DEV_FIMD0
 	select S3C_DEV_RTC
 	select S3C_DEV_WDT
 	select S3C_DEV_I2C1
@@ -112,6 +118,7 @@ config MACH_SMDKC210
 	select S3C_DEV_HSMMC3
 	select EXYNOS4_DEV_PD
 	select EXYNOS4_DEV_SYSMMU
+	select EXYNOS4_SETUP_FIMD0_24BPP
 	select EXYNOS4_SETUP_I2C1
 	select EXYNOS4_SETUP_SDHCI
 	help
@@ -120,6 +127,7 @@ config MACH_SMDKC210
 config MACH_SMDKV310
 	bool "SMDKV310"
 	select CPU_EXYNOS4210
+	select S5P_DEV_FIMD0
 	select S3C_DEV_RTC
 	select S3C_DEV_WDT
 	select S3C_DEV_I2C1
@@ -130,6 +138,7 @@ config MACH_SMDKV310
 	select SAMSUNG_DEV_KEYPAD
 	select EXYNOS4_DEV_PD
 	select EXYNOS4_DEV_SYSMMU
+	select EXYNOS4_SETUP_FIMD0_24BPP
 	select EXYNOS4_SETUP_I2C1
 	select EXYNOS4_SETUP_KEYPAD
 	select EXYNOS4_SETUP_SDHCI
diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile
index 60fe5ec..aa4d1f4 100644
--- a/arch/arm/mach-exynos4/Makefile
+++ b/arch/arm/mach-exynos4/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_EXYNOS4_DEV_PD)		+= dev-pd.o
 obj-$(CONFIG_EXYNOS4_DEV_SYSMMU)	+= dev-sysmmu.o
 
 obj-$(CONFIG_EXYNOS4_SETUP_FIMC)	+= setup-fimc.o
+obj-$(CONFIG_EXYNOS4_SETUP_FIMD0_24BPP)	+= setup-fimd0-24bpp.o
 obj-$(CONFIG_EXYNOS4_SETUP_I2C1)	+= setup-i2c1.o
 obj-$(CONFIG_EXYNOS4_SETUP_I2C2)	+= setup-i2c2.o
 obj-$(CONFIG_EXYNOS4_SETUP_I2C3)	+= setup-i2c3.o
diff --git a/arch/arm/mach-exynos4/cpu.c b/arch/arm/mach-exynos4/cpu.c
index 9babe44..778a5b0 100644
--- a/arch/arm/mach-exynos4/cpu.c
+++ b/arch/arm/mach-exynos4/cpu.c
@@ -19,9 +19,10 @@
 
 #include <plat/cpu.h>
 #include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/fb-core.h>
 #include <plat/exynos4.h>
 #include <plat/sdhci.h>
-#include <plat/devs.h>
 #include <plat/fimc-core.h>
 
 #include <mach/regs-irq.h>
@@ -132,6 +133,7 @@ void __init exynos4_map_io(void)
 	s3c_fimc_setname(1, "exynos4-fimc");
 	s3c_fimc_setname(2, "exynos4-fimc");
 	s3c_fimc_setname(3, "exynos4-fimc");
+	s5p_fb_setname(0, "exynos4-fb");	/* FIMD0 */
 }
 
 void __init exynos4_init_clocks(int xtal)
diff --git a/arch/arm/mach-exynos4/include/mach/regs-fb.h b/arch/arm/mach-exynos4/include/mach/regs-fb.h
new file mode 100644
index 0000000..f320105
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/regs-fb.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2010 Ben Dooks <ben-linux@fluff.org>
+ *
+ * Dummy framebuffer to allow build for the moment.
+ *
+ * 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.
+*/
+
+#ifndef __ASM_ARCH_MACH_REGS_FB_H
+#define __ASM_ARCH_MACH_REGS_FB_H __FILE__
+
+#include <plat/regs-fb-v4.h>
+
+static inline unsigned int s3c_fb_pal_reg(unsigned int window, int reg)
+{
+	return 0x2400 + (window * 256 * 4) + reg;
+}
+
+#endif /* __ASM_ARCH_MACH_REGS_FB_H */
diff --git a/arch/arm/mach-exynos4/setup-fimd0-24bpp.c b/arch/arm/mach-exynos4/setup-fimd0-24bpp.c
new file mode 100644
index 0000000..3ca8555
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-fimd0-24bpp.c
@@ -0,0 +1,47 @@
+/* linux/arch/arm/mach-exynos4/setup-fimd0-24bpp.c
+ *
+ * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Base Exynos4 setup information for 24bpp LCD framebuffer
+ *
+ * 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.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+
+#include <plat/fb.h>
+#include <plat/gpio-cfg.h>
+
+#include <mach/regs-clock.h>
+#include <mach/regs-fb.h>
+#include <mach/map.h>
+
+void exynos4_fimd0_gpio_setup_24bpp(void)
+{
+	unsigned int reg = 0;
+
+	s3c_gpio_cfgrange_nopull(EXYNOS4_GPF0(0), 8, S3C_GPIO_SFN(2));
+	s3c_gpio_cfgrange_nopull(EXYNOS4_GPF1(0), 8, S3C_GPIO_SFN(2));
+	s3c_gpio_cfgrange_nopull(EXYNOS4_GPF2(0), 8, S3C_GPIO_SFN(2));
+	s3c_gpio_cfgrange_nopull(EXYNOS4_GPF3(0), 4, S3C_GPIO_SFN(2));
+
+	/*
+	 * Set DISPLAY_CONTROL register for Display path selection.
+	 *
+	 * DISPLAY_CONTROL[1:0]
+	 * ---------------------
+	 *  00 | MIE
+	 *  01 | MDINE
+	 *  10 | FIMD : selected
+	 *  11 | FIMD
+	 */
+	reg = __raw_readl(S3C_VA_SYS + 0x0210);
+	reg |= (1 << 1);
+	__raw_writel(reg, S3C_VA_SYS + 0x0210);
+}
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
index e98f5c5..46de16e 100644
--- a/arch/arm/plat-s5p/Kconfig
+++ b/arch/arm/plat-s5p/Kconfig
@@ -70,6 +70,11 @@ config S5P_DEV_FIMC3
 	help
 	  Compile in platform device definitions for FIMC controller 3
 
+config S5P_DEV_FIMD0
+	bool
+	help
+	  Compile in platform device definitions for FIMD controller 0
+
 config S5P_DEV_ONENAND
 	bool
 	help
diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
index e234cc4..eec7e24 100644
--- a/arch/arm/plat-s5p/Makefile
+++ b/arch/arm/plat-s5p/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_S5P_DEV_FIMC0)	+= dev-fimc0.o
 obj-$(CONFIG_S5P_DEV_FIMC1)	+= dev-fimc1.o
 obj-$(CONFIG_S5P_DEV_FIMC2)	+= dev-fimc2.o
 obj-$(CONFIG_S5P_DEV_FIMC3)	+= dev-fimc3.o
+obj-$(CONFIG_S5P_DEV_FIMD0)	+= dev-fimd0.o
 obj-$(CONFIG_S5P_DEV_ONENAND)	+= dev-onenand.o
 obj-$(CONFIG_S5P_DEV_CSIS0)	+= dev-csis0.o
 obj-$(CONFIG_S5P_DEV_CSIS1)	+= dev-csis1.o
diff --git a/arch/arm/plat-s5p/dev-fimd0.c b/arch/arm/plat-s5p/dev-fimd0.c
new file mode 100644
index 0000000..9e7176c
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-fimd0.c
@@ -0,0 +1,67 @@
+/* linux/arch/arm/plat-s5p/dev-fimd0.c
+ *
+ * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Core file for Samsung Display Controller (FIMD) driver
+ *
+ * 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.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/gfp.h>
+#include <linux/dma-mapping.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/fb.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s5p_fimd0_resource[] = {
+	[0] = {
+		.start  = S5P_PA_FIMD0,
+		.end    = S5P_PA_FIMD0 + SZ_32K - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = IRQ_FIMD0_VSYNC,
+		.end    = IRQ_FIMD0_VSYNC,
+		.flags  = IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start  = IRQ_FIMD0_FIFO,
+		.end    = IRQ_FIMD0_FIFO,
+		.flags  = IORESOURCE_IRQ,
+	},
+	[3] = {
+		.start  = IRQ_FIMD0_SYSTEM,
+		.end    = IRQ_FIMD0_SYSTEM,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static u64 fimd0_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s5p_device_fimd0 = {
+	.name           = "s5p-fb",
+	.id             = 0,
+	.num_resources  = ARRAY_SIZE(s5p_fimd0_resource),
+	.resource       = s5p_fimd0_resource,
+	.dev            = {
+		.dma_mask               = &fimd0_dmamask,
+		.coherent_dma_mask      = DMA_BIT_MASK(32),
+	},
+};
+
+void __init s5p_fimd0_set_platdata(struct s3c_fb_platdata *pd)
+{
+	s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata),
+			&s5p_device_fimd0);
+}
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 4af108f..370bd2b 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -45,6 +45,7 @@ extern struct platform_device s3c64xx_device_ac97;
 extern struct platform_device s3c_device_ts;
 
 extern struct platform_device s3c_device_fb;
+extern struct platform_device s5p_device_fimd0;
 extern struct platform_device s3c_device_ohci;
 extern struct platform_device s3c_device_lcd;
 extern struct platform_device s3c_device_wdt;
diff --git a/arch/arm/plat-samsung/include/plat/fb-core.h b/arch/arm/plat-samsung/include/plat/fb-core.h
index bca383e..6abcbf1 100644
--- a/arch/arm/plat-samsung/include/plat/fb-core.h
+++ b/arch/arm/plat-samsung/include/plat/fb-core.h
@@ -26,4 +26,19 @@ static inline void s3c_fb_setname(char *name)
 #endif
 }
 
+/* Re-define device name depending on support. */
+static inline void s5p_fb_setname(int id, char *name)
+{
+	switch (id) {
+#ifdef CONFIG_S5P_DEV_FIMD0
+	case 0:
+		s5p_device_fimd0.name = name;
+	break;
+#endif
+	default:
+		printk(KERN_ERR "%s: invalid device id(%d)\n", __func__, id);
+	break;
+	}
+}
+
 #endif /* __ASM_PLAT_FB_CORE_H */
diff --git a/arch/arm/plat-samsung/include/plat/fb.h b/arch/arm/plat-samsung/include/plat/fb.h
index cb3ca3a..01f10e4 100644
--- a/arch/arm/plat-samsung/include/plat/fb.h
+++ b/arch/arm/plat-samsung/include/plat/fb.h
@@ -74,6 +74,14 @@ struct s3c_fb_platdata {
 extern void s3c_fb_set_platdata(struct s3c_fb_platdata *pd);
 
 /**
+ * s5p_fimd0_set_platdata() - Setup the FB device with platform data.
+ * @pd: The platform data to set. The data is copied from the passed structure
+ *      so the machine data can mark the data __initdata so that any unused
+ *      machines will end up dumping their data at runtime.
+ */
+extern void s5p_fimd0_set_platdata(struct s3c_fb_platdata *pd);
+
+/**
  * s3c64xx_fb_gpio_setup_24bpp() - S3C64XX setup function for 24bpp LCD
  *
  * Initialise the GPIO for an 24bpp LCD display on the RGB interface.
@@ -94,4 +102,11 @@ extern void s5pc100_fb_gpio_setup_24bpp(void);
  */
 extern void s5pv210_fb_gpio_setup_24bpp(void);
 
+/**
+ * exynos4_fimd0_gpio_setup_24bpp() - Exynos4 setup function for 24bpp LCD0
+ *
+ * Initialise the GPIO for an 24bpp LCD display on the RGB interface 0.
+ */
+extern void exynos4_fimd0_gpio_setup_24bpp(void);
+
 #endif /* __PLAT_S3C_FB_H */
-- 
1.7.1


^ permalink raw reply related

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

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

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

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

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

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


^ permalink raw reply related

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

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

This patch adds support EXYNOS4 FIMD0 and LTE480WV LCD pannel.

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

diff --git a/arch/arm/mach-exynos4/mach-smdkc210.c b/arch/arm/mach-exynos4/mach-smdkc210.c
index e645f7a..360a50a 100644
--- a/arch/arm/mach-exynos4/mach-smdkc210.c
+++ b/arch/arm/mach-exynos4/mach-smdkc210.c
@@ -9,26 +9,33 @@
 */
 
 #include <linux/serial_core.h>
+#include <linux/delay.h>
 #include <linux/gpio.h>
+#include <linux/lcd.h>
 #include <linux/mmc/host.h>
 #include <linux/platform_device.h>
 #include <linux/smsc911x.h>
 #include <linux/io.h>
 #include <linux/i2c.h>
+#include <linux/clk.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 
+#include <video/platform_lcd.h>
+
 #include <plat/regs-serial.h>
 #include <plat/regs-srom.h>
 #include <plat/exynos4.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
+#include <plat/fb.h>
 #include <plat/sdhci.h>
 #include <plat/iic.h>
 #include <plat/pd.h>
 
 #include <mach/map.h>
+#include <mach/regs-fb.h>
 
 /* Following are default values for UCON, ULCON and UFCON UART registers */
 #define SMDKC210_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
@@ -111,6 +118,69 @@ static struct s3c_sdhci_platdata smdkc210_hsmmc3_pdata __initdata = {
 	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
 };
 
+static void lcd_lte480wv_set_power(struct plat_lcd_data *pd,
+				   unsigned int power)
+{
+	if (power) {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+		gpio_request(EXYNOS4_GPD0(1), "GPD0");
+		gpio_direction_output(EXYNOS4_GPD0(1), 1);
+		gpio_free(EXYNOS4_GPD0(1));
+#endif
+		/* fire nRESET on power up */
+		gpio_request(EXYNOS4_GPX0(6), "GPX0");
+
+		gpio_direction_output(EXYNOS4_GPX0(6), 1);
+		mdelay(100);
+
+		gpio_set_value(EXYNOS4_GPX0(6), 0);
+		mdelay(10);
+
+		gpio_set_value(EXYNOS4_GPX0(6), 1);
+		mdelay(10);
+
+		gpio_free(EXYNOS4_GPX0(6));
+	} else {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+		gpio_request(EXYNOS4_GPD0(1), "GPD0");
+		gpio_direction_output(EXYNOS4_GPD0(1), 0);
+		gpio_free(EXYNOS4_GPD0(1));
+#endif
+	}
+}
+
+static struct plat_lcd_data smdkc210_lcd_lte480wv_data = {
+	.set_power      = lcd_lte480wv_set_power,
+};
+
+static struct platform_device smdkc210_lcd_lte480wv = {
+	.name                   = "platform-lcd",
+	.dev.parent             = &s5p_device_fimd0.dev,
+	.dev.platform_data      = &smdkc210_lcd_lte480wv_data,
+};
+
+static struct s3c_fb_pd_win smdkc210_fb_win0 = {
+	.win_mode = {
+		.left_margin    = 13,
+		.right_margin   = 8,
+		.upper_margin   = 7,
+		.lower_margin   = 5,
+		.hsync_len      = 3,
+		.vsync_len      = 1,
+		.xres   = 800,
+		.yres   = 480,
+	},
+	.max_bpp        = 32,
+	.default_bpp    = 24,
+};
+
+static struct s3c_fb_platdata smdkc210_lcd0_pdata __initdata = {
+	.win[0]		= &smdkc210_fb_win0,
+	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+	.vidcon1	= VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+	.setup_gpio	= exynos4_fimd0_gpio_setup_24bpp,
+};
+
 static struct resource smdkc210_smsc911x_resources[] = {
 	[0] = {
 		.start	= EXYNOS4_PA_SROM_BANK(1),
@@ -165,6 +235,8 @@ static struct platform_device *smdkc210_devices[] __initdata = {
 	&exynos4_device_pd[PD_GPS],
 	&exynos4_device_sysmmu,
 	&samsung_asoc_dma,
+	&s5p_device_fimd0,
+	&smdkc210_lcd_lte480wv,
 	&smdkc210_smsc911x,
 };
 
@@ -191,6 +263,44 @@ static void __init smdkc210_smsc911x_init(void)
 		     (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
 }
 
+static int __init smdkc210_fimd0_setup_clock(void)
+{
+	struct clk *sclk = NULL;
+	struct clk *mout_mpll = NULL;
+
+	u32 rate = 0;
+
+	sclk = clk_get(&s5p_device_fimd0.dev, "sclk_fimd");
+	if (IS_ERR(sclk)) {
+		printk(KERN_ERR "failed to get sclk for fimd\n");
+		goto err_clk2;
+	}
+
+	mout_mpll = clk_get(NULL, "mout_mpll");
+	if (IS_ERR(mout_mpll)) {
+		printk(KERN_ERR "failed to get mout_mpll\n");
+		goto err_clk1;
+	}
+
+	clk_set_parent(sclk, mout_mpll);
+	if (!rate)
+		rate = 134000000;
+
+	clk_set_rate(sclk, rate);
+
+	clk_put(sclk);
+	clk_put(mout_mpll);
+
+	return 0;
+
+err_clk1:
+	clk_put(mout_mpll);
+err_clk2:
+	clk_put(sclk);
+
+	return -EINVAL;
+}
+
 static void __init smdkc210_map_io(void)
 {
 	s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -210,7 +320,11 @@ static void __init smdkc210_machine_init(void)
 	s3c_sdhci2_set_platdata(&smdkc210_hsmmc2_pdata);
 	s3c_sdhci3_set_platdata(&smdkc210_hsmmc3_pdata);
 
+	s5p_fimd0_set_platdata(&smdkc210_lcd0_pdata);
+
 	platform_add_devices(smdkc210_devices, ARRAY_SIZE(smdkc210_devices));
+
+	smdkc210_fimd0_setup_clock();
 }
 
 MACHINE_START(SMDKC210, "SMDKC210")
diff --git a/arch/arm/mach-exynos4/mach-smdkv310.c b/arch/arm/mach-exynos4/mach-smdkv310.c
index 1526764..7bc12b5 100644
--- a/arch/arm/mach-exynos4/mach-smdkv310.c
+++ b/arch/arm/mach-exynos4/mach-smdkv310.c
@@ -9,28 +9,35 @@
 */
 
 #include <linux/serial_core.h>
+#include <linux/delay.h>
 #include <linux/gpio.h>
+#include <linux/lcd.h>
 #include <linux/mmc/host.h>
 #include <linux/platform_device.h>
 #include <linux/smsc911x.h>
 #include <linux/io.h>
 #include <linux/i2c.h>
 #include <linux/input.h>
+#include <linux/clk.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 
+#include <video/platform_lcd.h>
+
 #include <plat/regs-serial.h>
 #include <plat/regs-srom.h>
 #include <plat/exynos4.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
+#include <plat/fb.h>
 #include <plat/keypad.h>
 #include <plat/sdhci.h>
 #include <plat/iic.h>
 #include <plat/pd.h>
 
 #include <mach/map.h>
+#include <mach/regs-fb.h>
 
 /* Following are default values for UCON, ULCON and UFCON UART registers */
 #define SMDKV310_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
@@ -113,6 +120,69 @@ static struct s3c_sdhci_platdata smdkv310_hsmmc3_pdata __initdata = {
 	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
 };
 
+static void lcd_lte480wv_set_power(struct plat_lcd_data *pd,
+				   unsigned int power)
+{
+	if (power) {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+		gpio_request(EXYNOS4_GPD0(1), "GPD0");
+		gpio_direction_output(EXYNOS4_GPD0(1), 1);
+		gpio_free(EXYNOS4_GPD0(1));
+#endif
+		/* fire nRESET on power up */
+		gpio_request(EXYNOS4_GPX0(6), "GPX0");
+
+		gpio_direction_output(EXYNOS4_GPX0(6), 1);
+		mdelay(100);
+
+		gpio_set_value(EXYNOS4_GPX0(6), 0);
+		mdelay(10);
+
+		gpio_set_value(EXYNOS4_GPX0(6), 1);
+		mdelay(10);
+
+		gpio_free(EXYNOS4_GPX0(6));
+	} else {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+		gpio_request(EXYNOS4_GPD0(1), "GPD0");
+		gpio_direction_output(EXYNOS4_GPD0(1), 0);
+		gpio_free(EXYNOS4_GPD0(1));
+#endif
+	}
+}
+
+static struct plat_lcd_data smdkv310_lcd_lte480wv_data = {
+	.set_power      = lcd_lte480wv_set_power,
+};
+
+static struct platform_device smdkv310_lcd_lte480wv = {
+	.name                   = "platform-lcd",
+	.dev.parent             = &s5p_device_fimd0.dev,
+	.dev.platform_data      = &smdkv310_lcd_lte480wv_data,
+};
+
+static struct s3c_fb_pd_win smdkv310_fb_win0 = {
+	.win_mode = {
+		.left_margin    = 13,
+		.right_margin   = 8,
+		.upper_margin   = 7,
+		.lower_margin   = 5,
+		.hsync_len      = 3,
+		.vsync_len      = 1,
+		.xres   = 800,
+		.yres   = 480,
+	},
+	.max_bpp        = 32,
+	.default_bpp    = 24,
+};
+
+static struct s3c_fb_platdata smdkv310_lcd0_pdata __initdata = {
+	.win[0]		= &smdkv310_fb_win0,
+	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+	.vidcon1	= VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+	.setup_gpio	= exynos4_fimd0_gpio_setup_24bpp,
+};
+
 static struct resource smdkv310_smsc911x_resources[] = {
 	[0] = {
 		.start	= EXYNOS4_PA_SROM_BANK(1),
@@ -187,6 +257,8 @@ static struct platform_device *smdkv310_devices[] __initdata = {
 	&exynos4_device_pd[PD_GPS],
 	&exynos4_device_sysmmu,
 	&samsung_asoc_dma,
+	&s5p_device_fimd0,
+	&smdkv310_lcd_lte480wv,
 	&smdkv310_smsc911x,
 };
 
@@ -213,6 +285,44 @@ static void __init smdkv310_smsc911x_init(void)
 		     (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
 }
 
+static int __init smdkv310_fimd0_setup_clock(void)
+{
+	struct clk *sclk = NULL;
+	struct clk *mout_mpll = NULL;
+
+	u32 rate = 0;
+
+	sclk = clk_get(&s5p_device_fimd0.dev, "sclk_fimd");
+	if (IS_ERR(sclk)) {
+		printk(KERN_ERR "failed to get sclk for fimd\n");
+		goto err_clk2;
+	}
+
+	mout_mpll = clk_get(NULL, "mout_mpll");
+	if (IS_ERR(mout_mpll)) {
+		printk(KERN_ERR "failed to get mout_mpll\n");
+		goto err_clk1;
+	}
+
+	clk_set_parent(sclk, mout_mpll);
+	if (!rate)
+		rate = 134000000;
+
+	clk_set_rate(sclk, rate);
+
+	clk_put(sclk);
+	clk_put(mout_mpll);
+
+	return 0;
+
+err_clk1:
+	clk_put(mout_mpll);
+err_clk2:
+	clk_put(sclk);
+
+	return -EINVAL;
+}
+
 static void __init smdkv310_map_io(void)
 {
 	s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -232,9 +342,13 @@ static void __init smdkv310_machine_init(void)
 	s3c_sdhci2_set_platdata(&smdkv310_hsmmc2_pdata);
 	s3c_sdhci3_set_platdata(&smdkv310_hsmmc3_pdata);
 
+	s5p_fimd0_set_platdata(&smdkv310_lcd0_pdata);
+
 	samsung_keypad_set_platdata(&smdkv310_keypad_data);
 
 	platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices));
+
+	smdkv310_fimd0_setup_clock();
 }
 
 MACHINE_START(SMDKV310, "SMDKV310")
-- 
1.7.1


^ permalink raw reply related

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

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

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

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

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

v2: change clock name of exynos4 FIMD: "fimd" -> "lcd"
     use 'has_clksel' variable in order to distinguish FIMD version
     add 'lcd_clk' that can be used for only lcd pixel clock
     add callback 'enable_clk()' to enable parent clock 'sclk_fimd'.
v3: remove the callback from the platform data structure
v4: move clk_enable(sfb->lcd_clk) under the if statement
v5: add clk_enable/disable(sfb->lcd_clk) to s3c_fb_runtime_suspend/resume().

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

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

^ permalink raw reply

* [PATCH] fbdev: sh_mobile_meram: Correct pointer check for YCbCr chroma plane
From: Damian Hobson-Garcia @ 2011-06-22  7:46 UTC (permalink / raw)
  To: linux-fbdev

The check was intended to test if we have a valid pointer to write into,
but it mistakenly checks the pointer contents instead.

Since a valid pointer is mandatory for the chroma data if a YCbCr format
is used, the pointer check has been removed.

Signed-off-by: Damian Hobson-Garcia <dhobsong@igel.co.jp>
---
Sorry, forgot to sign off the previous version.  Resend
 drivers/video/sh_mobile_meram.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c
index 216f7f7..a6f28b9 100644
--- a/drivers/video/sh_mobile_meram.c
+++ b/drivers/video/sh_mobile_meram.c
@@ -246,7 +246,7 @@ static inline void meram_get_next_icb_addr(struct sh_mobile_meram_info *pdata,
 		icb_offset = 0xc0000000 | (cfg->current_reg << 23);
 
 	*icb_addr_y = icb_offset | (cfg->icb[0].marker_icb << 24);
-	if ((*icb_addr_c) && is_nvcolor(cfg->pixelformat))
+	if (is_nvcolor(cfg->pixelformat))
 		*icb_addr_c = icb_offset | (cfg->icb[1].marker_icb << 24);
 }
 
-- 
1.7.1


^ permalink raw reply related

* [PATCH 0/5 v3] LCDC MERAM runtime PM support
From: Damian Hobson-Garcia @ 2011-06-22  7:49 UTC (permalink / raw)
  To: linux-fbdev

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

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

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

Changes from V2

* Change the names of the clk_on/clk_off callbacks to pm_get_sync/pm_put_sync
  to better reflect their actual functionality

* Make these callback functions static

* The private data structure definition was moved from sh_mobile_meram.h to
  sh_mobile_meram.c.  This has been moved into a separate patch

* Use the sh7372_add_device_to_domain() function to register the MERAM in
  the SH7372_A4LC domain.

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

 arch/arm/mach-shmobile/board-mackerel.c |    1 +
 drivers/video/sh_mobile_lcdcfb.c        |   10 +++
 drivers/video/sh_mobile_meram.c         |  106 +++++++++++++++++++++++++++++++
 drivers/video/sh_mobile_meram.h         |    8 ---
 include/video/sh_mobile_meram.h         |    6 ++
 5 files changed, 123 insertions(+), 8 deletions(-)


^ permalink raw reply

* [PATCH 1/5 v3] fbdev: sh_mobile_meram: Add enable/disble hooks for LCDC
From: Damian Hobson-Garcia @ 2011-06-22  7:49 UTC (permalink / raw)
  To: linux-fbdev

Add hooks to allow the LCDC to increase/decrease the MERAM PM reference
counts

Signed-off-by: Damian Hobson-Garcia <dhobsong@igel.co.jp>
---
Changes from V2
=======
* Change the names of the clk_on/clk_off callbacks to pm_get_sync/pm_put_sync
  to better reflect their actual functionality

* Make these callback functions static

 drivers/video/sh_mobile_meram.c |   27 +++++++++++++++++++++++++++
 include/video/sh_mobile_meram.h |    6 ++++++
 2 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c
index 9170c82..371f129 100644
--- a/drivers/video/sh_mobile_meram.c
+++ b/drivers/video/sh_mobile_meram.c
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/device.h>
+#include <linux/pm_runtime.h>
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
@@ -460,11 +461,33 @@ static int sh_mobile_meram_update(struct sh_mobile_meram_info *pdata,
 	return 0;
 }
 
+static int sh_mobile_meram_pm_get_sync(struct sh_mobile_meram_info *pdata)
+{
+	if (!pdata || !pdata->pdev)
+		return -EINVAL;
+
+	dev_dbg(&pdata->pdev->dev, "Enabling sh_mobile_meram clock.");
+	pm_runtime_get_sync(&pdata->pdev->dev);
+	return 0;
+}
+
+static int sh_mobile_meram_pm_put_sync(struct sh_mobile_meram_info *pdata)
+{
+	if (!pdata || !pdata->pdev)
+		return -EINVAL;
+
+	dev_dbg(&pdata->pdev->dev, "Disabling sh_mobile_meram clock.");
+	pm_runtime_put_sync(&pdata->pdev->dev);
+	return 0;
+}
+
 static struct sh_mobile_meram_ops sh_mobile_meram_ops = {
 	.module			= THIS_MODULE,
 	.meram_register		= sh_mobile_meram_register,
 	.meram_unregister	= sh_mobile_meram_unregister,
 	.meram_update		= sh_mobile_meram_update,
+	.meram_pm_put_sync	= sh_mobile_meram_pm_put_sync,
+	.meram_pm_get_sync	= sh_mobile_meram_pm_get_sync,
 };
 
 /*
@@ -515,6 +538,8 @@ static int __devinit sh_mobile_meram_probe(struct platform_device *pdev)
 	if (pdata->addr_mode = SH_MOBILE_MERAM_MODE1)
 		meram_write_reg(priv->base, MEVCR1, 1 << 29);
 
+	pm_runtime_enable(&pdev->dev);
+
 	dev_info(&pdev->dev, "sh_mobile_meram initialized.");
 
 	return 0;
@@ -530,6 +555,8 @@ static int sh_mobile_meram_remove(struct platform_device *pdev)
 {
 	struct sh_mobile_meram_priv *priv = platform_get_drvdata(pdev);
 
+	pm_runtime_disable(&pdev->dev);
+
 	if (priv->base)
 		iounmap(priv->base);
 
diff --git a/include/video/sh_mobile_meram.h b/include/video/sh_mobile_meram.h
index af602d6..f213b6d 100644
--- a/include/video/sh_mobile_meram.h
+++ b/include/video/sh_mobile_meram.h
@@ -63,6 +63,12 @@ struct sh_mobile_meram_ops {
 			    unsigned long base_addr_c,
 			    unsigned long *icb_addr_y,
 			    unsigned long *icb_addr_c);
+
+	/* enable meram clock */
+	int (*meram_pm_get_sync)(struct sh_mobile_meram_info *meram_dev);
+
+	/* disable meram clock */
+	int (*meram_pm_put_sync)(struct sh_mobile_meram_info *meram_dev);
 };
 
 #endif /* __VIDEO_SH_MOBILE_MERAM_H__  */
-- 
1.7.1


^ permalink raw reply related

* [PATCH 2/5 v3] fbdev: sh_mobile_meram: Enable/disable MERAM along with LCDC
From: Damian Hobson-Garcia @ 2011-06-22  7:49 UTC (permalink / raw)
  To: linux-fbdev

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

Signed-off-by: Damian Hobson-Garcia <dhobsong@igel.co.jp>
---
Changes from V2
=======
* Change the names of the clk_on/clk_off callbacks to pm_get_sync/pm_put_sync
  to better reflect their actual functionality

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

diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 019dbd3..78cc828 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -259,6 +259,11 @@ static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv)
 		pm_runtime_get_sync(priv->dev);
 		if (priv->dot_clk)
 			clk_enable(priv->dot_clk);
+		if (priv->meram_dev && priv->meram_dev->ops) {
+			struct sh_mobile_meram_info *mdev;
+			mdev = priv->meram_dev;
+			mdev->ops->meram_pm_get_sync(mdev);
+		}
 	}
 }
 
@@ -267,6 +272,11 @@ static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv)
 	if (atomic_sub_return(1, &priv->hw_usecnt) = -1) {
 		if (priv->dot_clk)
 			clk_disable(priv->dot_clk);
+		if (priv->meram_dev && priv->meram_dev->ops) {
+			struct sh_mobile_meram_info *mdev;
+			mdev = priv->meram_dev;
+			mdev->ops->meram_pm_put_sync(mdev);
+		}
 		pm_runtime_put(priv->dev);
 	}
 }
-- 
1.7.1


^ permalink raw reply related

* [PATCH 3/5] fbdev: sh_mobile_meram: Move private data from .h to .c
From: Damian Hobson-Garcia @ 2011-06-22  7:49 UTC (permalink / raw)
  To: linux-fbdev

There is no reason for sh_mobile_meram_priv to be in the .h file
since it should be private to sh_mobile_meram.c

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

diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c
index 371f129..cc71cbf 100644
--- a/drivers/video/sh_mobile_meram.c
+++ b/drivers/video/sh_mobile_meram.c
@@ -37,6 +37,14 @@
 #define MEQSEL1 0x40
 #define MEQSEL2 0x44
 
+struct sh_mobile_meram_priv {
+	void __iomem	*base;
+	struct mutex	lock;
+	unsigned long	used_icb;
+	int		used_meram_cache_regions;
+	unsigned long	used_meram_cache[SH_MOBILE_MERAM_ICB_NUM];
+};
+
 /* settings */
 #define MERAM_SEC_LINE 15
 #define MERAM_LINE_WIDTH 2048
diff --git a/drivers/video/sh_mobile_meram.h b/drivers/video/sh_mobile_meram.h
index 82c54fb..1615204 100644
--- a/drivers/video/sh_mobile_meram.h
+++ b/drivers/video/sh_mobile_meram.h
@@ -17,14 +17,6 @@
 #define SH_MOBILE_MERAM_CACHE_OFFSET(p)	((p) >> 16)
 #define SH_MOBILE_MERAM_CACHE_SIZE(p)	((p) & 0xffff)
 
-struct sh_mobile_meram_priv {
-	void __iomem	*base;
-	struct mutex	lock;
-	unsigned long	used_icb;
-	int		used_meram_cache_regions;
-	unsigned long	used_meram_cache[SH_MOBILE_MERAM_ICB_NUM];
-};
-
 int sh_mobile_meram_alloc_icb(const struct sh_mobile_meram_cfg *cfg,
 		   int xres,
 		   int yres,
-- 
1.7.1


^ permalink raw reply related

* [PATCH 4/5 v3] fbdev: sh_mobile_meram: Backup/restore device registers on shutdown/resume
From: Damian Hobson-Garcia @ 2011-06-22  7:49 UTC (permalink / raw)
  To: linux-fbdev

Save and reconfigure the MERAM registers when the MERAM is powered down
and restored

Signed-off-by: Damian Hobson-Garcia <dhobsong@igel.co.jp>
---
Changes from V2
=======
* The private data structure definition was moved from sh_mobile_meram.h to
  sh_mobile_meram.c.  This has been moved into a separate patch

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

diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c
index cc71cbf..7afd77a 100644
--- a/drivers/video/sh_mobile_meram.c
+++ b/drivers/video/sh_mobile_meram.c
@@ -37,12 +37,31 @@
 #define MEQSEL1 0x40
 #define MEQSEL2 0x44
 
+static unsigned long common_regs[] = {
+	MEVCR1,
+	MEQSEL1,
+	MEQSEL2,
+};
+#define CMN_REGS_SIZE ARRAY_SIZE(common_regs)
+
+static unsigned long icb_regs[] = {
+	MExxCTL,
+	MExxBSIZE,
+	MExxMNCF,
+	MExxSARA,
+	MExxSARB,
+	MExxSBSIZE,
+};
+#define ICB_REGS_SIZE ARRAY_SIZE(icb_regs)
+
 struct sh_mobile_meram_priv {
 	void __iomem	*base;
 	struct mutex	lock;
 	unsigned long	used_icb;
 	int		used_meram_cache_regions;
 	unsigned long	used_meram_cache[SH_MOBILE_MERAM_ICB_NUM];
+	unsigned long	cmn_saved_regs[CMN_REGS_SIZE];
+	unsigned long	icb_saved_regs[ICB_REGS_SIZE * SH_MOBILE_MERAM_ICB_NUM];
 };
 
 /* settings */
@@ -489,6 +508,57 @@ int sh_mobile_meram_pm_put_sync(struct sh_mobile_meram_info *pdata)
 	return 0;
 }
 
+static int sh_mobile_meram_runtime_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct sh_mobile_meram_priv *priv = platform_get_drvdata(pdev);
+	int k, j;
+
+	for (k = 0; k < CMN_REGS_SIZE; k++)
+		priv->cmn_saved_regs[k] = meram_read_reg(priv->base,
+			common_regs[k]);
+
+	for (j = 0; j < 32; j++) {
+		if (!test_bit(j, &priv->used_icb))
+			continue;
+		for (k = 0; k < ICB_REGS_SIZE; k++) {
+			priv->icb_saved_regs[j * ICB_REGS_SIZE + k] +				meram_read_icb(priv->base, j, icb_regs[k]);
+			/* Reset ICB on resume */
+			if (icb_regs[k] = MExxCTL)
+				priv->icb_saved_regs[j * ICB_REGS_SIZE + k] +					0x70;
+		}
+	}
+	return 0;
+}
+
+static int sh_mobile_meram_runtime_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct sh_mobile_meram_priv *priv = platform_get_drvdata(pdev);
+	int k, j;
+
+	for (j = 0; j < 32; j++) {
+		if (!test_bit(j, &priv->used_icb))
+			continue;
+		for (k = 0; k < ICB_REGS_SIZE; k++) {
+			meram_write_icb(priv->base, j, icb_regs[k],
+			priv->icb_saved_regs[j * ICB_REGS_SIZE + k]);
+		}
+	}
+
+	for (k = 0; k < CMN_REGS_SIZE; k++)
+		meram_write_reg(priv->base, common_regs[k],
+			priv->cmn_saved_regs[k]);
+	return 0;
+}
+
+static const struct dev_pm_ops sh_mobile_meram_dev_pm_ops = {
+	.runtime_suspend = sh_mobile_meram_runtime_suspend,
+	.runtime_resume = sh_mobile_meram_runtime_resume,
+};
+
 static struct sh_mobile_meram_ops sh_mobile_meram_ops = {
 	.module			= THIS_MODULE,
 	.meram_register		= sh_mobile_meram_register,
@@ -579,6 +649,7 @@ static struct platform_driver sh_mobile_meram_driver = {
 	.driver	= {
 		.name		= "sh_mobile_meram",
 		.owner		= THIS_MODULE,
+		.pm		= &sh_mobile_meram_dev_pm_ops,
 	},
 	.probe		= sh_mobile_meram_probe,
 	.remove		= sh_mobile_meram_remove,
-- 
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