Linux Framebuffer Layer development
 help / color / mirror / Atom feed
* Re: [PATCH v7.1 00/19] Rework OMAP4+ HDMI audio support
From: Mark Brown @ 2014-11-21 16:14 UTC (permalink / raw)
  To: Jyri Sarha
  Cc: Tomi Valkeinen, alsa-devel, linux-fbdev, linux-omap,
	peter.ujfalusi, liam.r.girdwood
In-Reply-To: <546F317B.9030004@ti.com>

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

On Fri, Nov 21, 2014 at 02:35:07PM +0200, Jyri Sarha wrote:
> On 11/21/2014 01:23 PM, Mark Brown wrote:

> >With this specific series I also need to figure out what all the video
> >side is about (like I said earlier a lot of the patches look like
> >they're supposed to be simple fixes for the video code not terribly
> >closely tied to the rest of the series but none of them are getting
> >applied) and what the end goal is beyond mechanically moving code.

> The end goal of this series is to fix OMAP HDMI audio, that got broken
> couple of releases ago. At the same time I cleaned up the old complex scheme
> to make the connection between the video and audio parts and allow multiple
> HDMI devices (DSS side is not ready for this yet, but audio side is).

But in what way is it broken and how did this happen?  Why are none of
the patches which look like they're supposed to be bug fixes early on in
the series getting applied?  I had thought this was just a lack of
interest on the video side but it seems there's some other problems
since the series has apparently been discussed off-list and still it's
just as big as it was initially.

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

^ permalink raw reply

* Re: [PATCH v7.1 00/19] Rework OMAP4+ HDMI audio support
From: Mark Brown @ 2014-11-21 16:38 UTC (permalink / raw)
  To: Jyri Sarha
  Cc: Tomi Valkeinen, alsa-devel, linux-fbdev, linux-omap,
	peter.ujfalusi, liam.r.girdwood
In-Reply-To: <546F2BA3.9050203@ti.com>

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

On Fri, Nov 21, 2014 at 02:10:11PM +0200, Jyri Sarha wrote:

> OMAP HDMI audio is fundamentally different to the case on Armada or on BBB.
> In omap the whole HDMI IP is integrated to the SoC and there really is no
> codec in the ASoC sense. The the cpu-dai transmits the audio directly to
> hdmi wire and there is no i2s bus involved. So this case should not be mixed
> with the patches Jean-Francois working on. The code is also orthogonal in
> that sense that the latest omap-hdmi-audio uses the generic dymmy codec.

The discussion seemed to be about what to do with unplugged connections
which isn't what you're talking about there and does seem like an area
where we should at least be aiming for common behaviour even if not a
common implementation.

There's also all the stuff about parsing EDIDs for capabilities which
would seem to be related to that but seems to have gone off into the
weeds.

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

^ permalink raw reply

* [PATCH] video: fbmon: Check Standard Timing against DMT and maxclk
From: David Ung @ 2014-11-22  3:21 UTC (permalink / raw)
  To: linux-fbdev

fbmon may generate mode timings that are out of spec of the monitor.
eg DELL U2410 has a max clock 170mhz but advertises a resolutions of
1920x1200@60 in its Standard Timings, fbmon creates a mode using the
GTF timing calculation which gave it a 193mhz clock.
This patch add the VESA Display Monitor Timing (DMT) table.
During parsing of Standard Timings, it compare the 2 byte STD code
with DMT to see what the VESA mode should be.  If there is no entry
in the vesa_modes table or no match found, it fallsback to the GTF
timings.  A final check to see if the mode can be supported by the
monitor by comparing against monspecs.dclkmax.

Signed-off-by: David Ung <davidu@nvidia.com>
---
 drivers/video/fbdev/core/fbmon.c  |  47 ++++++++++------
 drivers/video/fbdev/core/modedb.c | 111 ++++++++++++++++++++++++++++++++++++++
 include/linux/fb.h                |  12 ++++-
 3 files changed, 153 insertions(+), 17 deletions(-)

diff --git a/drivers/video/fbdev/core/fbmon.c b/drivers/video/fbdev/core/fbmon.c
index 5b0e313..cc3ea6c8 100644
--- a/drivers/video/fbdev/core/fbmon.c
+++ b/drivers/video/fbdev/core/fbmon.c
@@ -496,7 +496,7 @@ static int get_est_timing(unsigned char *block, struct fb_videomode *mode)
 }
 
 static int get_std_timing(unsigned char *block, struct fb_videomode *mode,
-		int ver, int rev)
+			  int ver, int rev, struct fb_monspecs *specs)
 {
 	int xres, yres = 0, refresh, ratio, i;
 
@@ -526,26 +526,39 @@ static int get_std_timing(unsigned char *block, struct fb_videomode *mode,
 	refresh = (block[1] & 0x3f) + 60;
 
 	DPRINTK("      %dx%d@%dHz\n", xres, yres, refresh);
-	for (i = 0; i < VESA_MODEDB_SIZE; i++) {
-		if (vesa_modes[i].xres = xres &&
-		    vesa_modes[i].yres = yres &&
-		    vesa_modes[i].refresh = refresh) {
-			*mode = vesa_modes[i];
+	for (i = 0; i < DMT_SIZE; i++) {
+		u32 std_2byte_code = block[0] << 8 | block[1];
+
+		if (std_2byte_code = dmt_modes[i].std_2byte_code) {
+			if (!dmt_modes[i].mode)
+				break;
+			*mode = *dmt_modes[i].mode;
 			mode->flag |= FB_MODE_IS_STANDARD;
-			return 1;
+			DPRINTK("        DMT id=%d\n", dmt_modes[i].dmt_id);
+			break;
 		}
 	}
-	calc_mode_timings(xres, yres, refresh, mode);
+
+	if (i = DMT_SIZE || !dmt_modes[i].mode)
+		calc_mode_timings(xres, yres, refresh, mode);
+
+	/* Check the mode we got is within valid spec of the monitor */
+	if (specs && specs->dclkmax
+	    && PICOS2KHZ(mode->pixclock) * 1000 > specs->dclkmax) {
+		DPRINTK("        mode exceed max DCLK\n");
+		return 0;
+	}
+
 	return 1;
 }
 
-static int get_dst_timing(unsigned char *block,
-			  struct fb_videomode *mode, int ver, int rev)
+static int get_dst_timing(unsigned char *block, struct fb_videomode *mode,
+			  int ver, int rev, struct fb_monspecs *specs)
 {
 	int j, num = 0;
 
 	for (j = 0; j < 6; j++, block += STD_TIMING_DESCRIPTION_SIZE)
-		num += get_std_timing(block, &mode[num], ver, rev);
+		num += get_std_timing(block, &mode[num], ver, rev, specs);
 
 	return num;
 }
@@ -601,7 +614,8 @@ static void get_detailed_timing(unsigned char *block,
  * This function builds a mode database using the contents of the EDID
  * data
  */
-static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
+static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize,
+					     struct fb_monspecs *specs)
 {
 	struct fb_videomode *mode, *m;
 	unsigned char *block;
@@ -643,12 +657,13 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
 	DPRINTK("   Standard Timings\n");
 	block = edid + STD_TIMING_DESCRIPTIONS_START;
 	for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE)
-		num += get_std_timing(block, &mode[num], ver, rev);
+		num += get_std_timing(block, &mode[num], ver, rev, specs);
 
 	block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
 	for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) {
 		if (block[0] = 0x00 && block[1] = 0x00 && block[3] = 0xfa)
-			num += get_dst_timing(block + 5, &mode[num], ver, rev);
+			num += get_dst_timing(block + 5, &mode[num],
+					      ver, rev, specs);
 	}
 
 	/* Yikes, EDID data is totally useless */
@@ -707,7 +722,7 @@ static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs)
 		int num_modes, hz, hscan, pixclock;
 		int vtotal, htotal;
 
-		modes = fb_create_modedb(edid, &num_modes);
+		modes = fb_create_modedb(edid, &num_modes, specs);
 		if (!modes) {
 			DPRINTK("None Available\n");
 			return 1;
@@ -964,7 +979,7 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs)
 	DPRINTK("   Display Characteristics:\n");
 	get_monspecs(edid, specs);
 
-	specs->modedb = fb_create_modedb(edid, &specs->modedb_len);
+	specs->modedb = fb_create_modedb(edid, &specs->modedb_len, specs);
 
 	/*
 	 * Workaround for buggy EDIDs that sets that the first
diff --git a/drivers/video/fbdev/core/modedb.c b/drivers/video/fbdev/core/modedb.c
index 388f797..858a97e 100644
--- a/drivers/video/fbdev/core/modedb.c
+++ b/drivers/video/fbdev/core/modedb.c
@@ -468,8 +468,119 @@ const struct fb_videomode vesa_modes[] = {
 	/* 33 1920x1440-75 VESA */
 	{ NULL, 75, 1920, 1440, 3367, 352, 144, 56, 1, 224, 3,
 	  FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+	/* 34 1920x1200-60 RB VESA */
+	{ NULL, 60, 1920, 1200, 6493, 80, 48, 26, 3, 32, 6,
+	  FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+	/* 35 1920x1200-60 VESA */
+	{ NULL, 60, 1920, 1200, 5174, 336, 136, 36, 3, 200, 6,
+	  FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+	/* 36 1920x1200-75 VESA */
+	{ NULL, 75, 1920, 1200, 4077, 344, 136, 46, 3, 208, 6,
+	  FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+	/* 37 1920x1200-85 VESA */
+	{ NULL, 85, 1920, 1200, 3555, 352, 144, 53, 3, 208, 6,
+	  FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+	/* 38 2560x1600-60 RB VESA */
+	{ NULL, 60, 2560, 1600, 3724, 80, 48, 37, 3, 32, 6,
+	  FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+	/* 39 2560x1600-60 VESA */
+	{ NULL, 60, 2560, 1600, 2869, 472, 192, 49, 3, 280, 6,
+	  FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+	/* 40 2560x1600-75 VESA */
+	{ NULL, 75, 2560, 1600, 2256, 488, 208, 63, 3, 280, 6,
+	  FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+	/* 41 2560x1600-85 VESA */
+	{ NULL, 85, 2560, 1600, 1979, 488, 208, 73, 3, 280, 6,
+	  FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+	/* 42 2560x1600-120 RB VESA */
+	{ NULL, 120, 2560, 1600, 1809, 80, 48, 85, 3, 32, 6,
+	  FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
 };
 EXPORT_SYMBOL(vesa_modes);
+
+const struct dmt_videomode dmt_modes[DMT_SIZE] = {
+	{ 0x01, 0x0000, 0x000000, &vesa_modes[0] },
+	{ 0x02, 0x3119, 0x000000, &vesa_modes[1] },
+	{ 0x03, 0x0000, 0x000000, &vesa_modes[2] },
+	{ 0x04, 0x3140, 0x000000, &vesa_modes[3] },
+	{ 0x05, 0x314c, 0x000000, &vesa_modes[4] },
+	{ 0x06, 0x314f, 0x000000, &vesa_modes[5] },
+	{ 0x07, 0x3159, 0x000000, &vesa_modes[6] },
+	{ 0x08, 0x0000, 0x000000, &vesa_modes[7] },
+	{ 0x09, 0x4540, 0x000000, &vesa_modes[8] },
+	{ 0x0a, 0x454c, 0x000000, &vesa_modes[9] },
+	{ 0x0b, 0x454f, 0x000000, &vesa_modes[10] },
+	{ 0x0c, 0x4559, 0x000000, &vesa_modes[11] },
+	{ 0x0d, 0x0000, 0x000000, 0 },
+	{ 0x0e, 0x0000, 0x000000, 0 },
+	{ 0x0f, 0x0000, 0x000000, &vesa_modes[12] },
+	{ 0x10, 0x6140, 0x000000, &vesa_modes[13] },
+	{ 0x11, 0x614a, 0x000000, &vesa_modes[14] },
+	{ 0x12, 0x614f, 0x000000, &vesa_modes[15] },
+	{ 0x13, 0x6159, 0x000000, &vesa_modes[16] },
+	{ 0x14, 0x0000, 0x000000, 0 },
+	{ 0x15, 0x714f, 0x000000, &vesa_modes[17] },
+	{ 0x16, 0x0000, 0x7f1c21, 0 },
+	{ 0x17, 0x0000, 0x7f1c28, 0 },
+	{ 0x18, 0x0000, 0x7f1c44, 0 },
+	{ 0x19, 0x0000, 0x7f1c62, 0 },
+	{ 0x1a, 0x0000, 0x000000, 0 },
+	{ 0x1b, 0x0000, 0x8f1821, 0 },
+	{ 0x1c, 0x8100, 0x8f1828, 0 },
+	{ 0x1d, 0x810f, 0x8f1844, 0 },
+	{ 0x1e, 0x8119, 0x8f1862, 0 },
+	{ 0x1f, 0x0000, 0x000000, 0 },
+	{ 0x20, 0x8140, 0x000000, &vesa_modes[18] },
+	{ 0x21, 0x8159, 0x000000, &vesa_modes[19] },
+	{ 0x22, 0x0000, 0x000000, 0 },
+	{ 0x23, 0x8180, 0x000000, &vesa_modes[20] },
+	{ 0x24, 0x818f, 0x000000, &vesa_modes[21] },
+	{ 0x25, 0x8199, 0x000000, &vesa_modes[22] },
+	{ 0x26, 0x0000, 0x000000, 0 },
+	{ 0x27, 0x0000, 0x000000, 0 },
+	{ 0x28, 0x0000, 0x000000, 0 },
+	{ 0x29, 0x0000, 0x0c2021, 0 },
+	{ 0x2a, 0x9040, 0x0c2028, 0 },
+	{ 0x2b, 0x904f, 0x0c2044, 0 },
+	{ 0x2c, 0x9059, 0x0c2062, 0 },
+	{ 0x2d, 0x0000, 0x000000, 0 },
+	{ 0x2e, 0x9500, 0xc11821, 0 },
+	{ 0x2f, 0x9500, 0xc11828, 0 },
+	{ 0x30, 0x950f, 0xc11844, 0 },
+	{ 0x31, 0x9519, 0xc11868, 0 },
+	{ 0x32, 0x0000, 0x000000, 0 },
+	{ 0x33, 0xa940, 0x000000, &vesa_modes[23] },
+	{ 0x34, 0xa945, 0x000000, &vesa_modes[24] },
+	{ 0x35, 0xa94a, 0x000000, &vesa_modes[25] },
+	{ 0x36, 0xa94f, 0x000000, &vesa_modes[26] },
+	{ 0x37, 0xa959, 0x000000, &vesa_modes[27] },
+	{ 0x38, 0x0000, 0x000000, 0 },
+	{ 0x39, 0x0000, 0x0c2821, 0 },
+	{ 0x3a, 0xb300, 0x0c2828, 0 },
+	{ 0x3b, 0xb30f, 0x0c2844, 0 },
+	{ 0x3c, 0xb319, 0x0c2868, 0 },
+	{ 0x3d, 0x0000, 0x000000, 0 },
+	{ 0x3e, 0xc140, 0x000000, &vesa_modes[28] },
+	{ 0x3f, 0xc14f, 0x000000, &vesa_modes[29] },
+	{ 0x40, 0x0000, 0x000000, 0 },
+	{ 0x41, 0xc940, 0x000000, &vesa_modes[30] },
+	{ 0x42, 0xc94f, 0x000000, &vesa_modes[31] },
+	{ 0x43, 0x0000, 0x000000, 0 },
+	{ 0x44, 0x0000, 0x572821, &vesa_modes[34] },
+	{ 0x45, 0xd100, 0x572828, &vesa_modes[35] },
+	{ 0x46, 0xd10f, 0x572844, &vesa_modes[36] },
+	{ 0x47, 0xd119, 0x572862, &vesa_modes[37] },
+	{ 0x48, 0x0000, 0x000000, 0 },
+	{ 0x49, 0xd140, 0x000000, &vesa_modes[32] },
+	{ 0x4a, 0xd14f, 0x000000, &vesa_modes[33] },
+	{ 0x4b, 0x0000, 0x000000, 0 },
+	{ 0x4c, 0x0000, 0x1f3821, &vesa_modes[38] },
+	{ 0x4d, 0x0000, 0x1f3828, &vesa_modes[39] },
+	{ 0x4e, 0x0000, 0x1f3844, &vesa_modes[40] },
+	{ 0x4f, 0x0000, 0x1f3862, &vesa_modes[41] },
+	{ 0x50, 0x0000, 0x000000, &vesa_modes[42] },
+};
+EXPORT_SYMBOL(dmt_modes);
 #endif /* CONFIG_FB_MODE_HELPERS */
 
 /**
diff --git a/include/linux/fb.h b/include/linux/fb.h
index 09bb7a1..043f328 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -726,7 +726,9 @@ extern int fb_videomode_from_videomode(const struct videomode *vm,
 				       struct fb_videomode *fbmode);
 
 /* drivers/video/modedb.c */
-#define VESA_MODEDB_SIZE 34
+#define VESA_MODEDB_SIZE 43
+#define DMT_SIZE 0x50
+
 extern void fb_var_to_videomode(struct fb_videomode *mode,
 				const struct fb_var_screeninfo *var);
 extern void fb_videomode_to_var(struct fb_var_screeninfo *var,
@@ -777,9 +779,17 @@ struct fb_videomode {
 	u32 flag;
 };
 
+struct dmt_videomode {
+	u32 dmt_id;
+	u32 std_2byte_code;
+	u32 cvt_3byte_code;
+	const struct fb_videomode *mode;
+};
+
 extern const char *fb_mode_option;
 extern const struct fb_videomode vesa_modes[];
 extern const struct fb_videomode cea_modes[64];
+extern const struct dmt_videomode dmt_modes[];
 
 struct fb_modelist {
 	struct list_head list;
-- 
1.8.1.5


^ permalink raw reply related

* [PATCH 1/1] video: fbdev-LCDC: Deletion of an unnecessary check before the function call "vfree"
From: SF Markus Elfring @ 2014-11-22 16:00 UTC (permalink / raw)
  To: Jean-Christophe Plagniol-Villard, Tomi Valkeinen, linux-fbdev
  Cc: LKML, kernel-janitors, Julia Lawall
In-Reply-To: <5317A59D.4@users.sourceforge.net>

From: Markus Elfring <elfring@users.sourceforge.net>
Date: Sat, 22 Nov 2014 16:51:31 +0100

The vfree() function performs also input parameter validation.
Thus the test around the call is not needed.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
 drivers/video/fbdev/sh_mobile_lcdcfb.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/sh_mobile_lcdcfb.c b/drivers/video/fbdev/sh_mobile_lcdcfb.c
index 2bcc84a..cfde21d 100644
--- a/drivers/video/fbdev/sh_mobile_lcdcfb.c
+++ b/drivers/video/fbdev/sh_mobile_lcdcfb.c
@@ -2181,8 +2181,7 @@ sh_mobile_lcdc_channel_fb_cleanup(struct sh_mobile_lcdc_chan *ch)
 	if (!info || !info->device)
 		return;
 
-	if (ch->sglist)
-		vfree(ch->sglist);
+	vfree(ch->sglist);
 
 	fb_dealloc_cmap(&info->cmap);
 	framebuffer_release(info);
-- 
2.1.3


^ permalink raw reply related

* [PATCH 1/1] video: uvesafb: Deletion of an unnecessary check before the function call "uvesafb_free"
From: SF Markus Elfring @ 2014-11-23 10:11 UTC (permalink / raw)
  To: Jean-Christophe Plagniol-Villard, Michal Januszewski,
	Tomi Valkeinen, linux-fbdev
  Cc: LKML, kernel-janitors, Julia Lawall
In-Reply-To: <5317A59D.4@users.sourceforge.net>

From: Markus Elfring <elfring@users.sourceforge.net>
Date: Sun, 23 Nov 2014 11:00:26 +0100

The uvesafb_free() function tests whether its argument is NULL and then
returns immediately. Thus the test around the call is not needed.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
 drivers/video/fbdev/uvesafb.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c
index 509d452..f718627 100644
--- a/drivers/video/fbdev/uvesafb.c
+++ b/drivers/video/fbdev/uvesafb.c
@@ -1219,8 +1219,7 @@ static int uvesafb_release(struct fb_info *info, int user)
 	uvesafb_vbe_state_restore(par, par->vbe_state_orig);
 out:
 	atomic_dec(&par->ref_count);
-	if (task)
-		uvesafb_free(task);
+	uvesafb_free(task);
 	return 0;
 }
 
-- 
2.1.3


^ permalink raw reply related

* [PATCH 1/1] video: udlfb: Deletion of unnecessary checks before the function call "vfree"
From: SF Markus Elfring @ 2014-11-23 10:44 UTC (permalink / raw)
  To: Jean-Christophe Plagniol-Villard, Tomi Valkeinen, linux-fbdev
  Cc: LKML, kernel-janitors, Julia Lawall
In-Reply-To: <5317A59D.4@users.sourceforge.net>

From: Markus Elfring <elfring@users.sourceforge.net>
Date: Sun, 23 Nov 2014 11:40:47 +0100

The vfree() function performs also input parameter validation. Thus the test
around the call is not needed.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
 drivers/video/fbdev/udlfb.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/video/fbdev/udlfb.c b/drivers/video/fbdev/udlfb.c
index 77b890e..01fff0c 100644
--- a/drivers/video/fbdev/udlfb.c
+++ b/drivers/video/fbdev/udlfb.c
@@ -922,8 +922,7 @@ static void dlfb_free(struct kref *kref)
 {
 	struct dlfb_data *dev = container_of(kref, struct dlfb_data, kref);
 
-	if (dev->backing_buffer)
-		vfree(dev->backing_buffer);
+	vfree(dev->backing_buffer);
 
 	kfree(dev->edid);
 
@@ -953,8 +952,7 @@ static void dlfb_free_framebuffer(struct dlfb_data *dev)
 			fb_dealloc_cmap(&info->cmap);
 		if (info->monspecs.modedb)
 			fb_destroy_modedb(info->monspecs.modedb);
-		if (info->screen_base)
-			vfree(info->screen_base);
+		vfree(info->screen_base);
 
 		fb_destroy_modelist(&info->modelist);
 
@@ -1203,8 +1201,7 @@ static int dlfb_realloc_framebuffer(struct dlfb_data *dev, struct fb_info *info)
 		if (!new_back)
 			pr_info("No shadow/backing buffer allocated\n");
 		else {
-			if (dev->backing_buffer)
-				vfree(dev->backing_buffer);
+			vfree(dev->backing_buffer);
 			dev->backing_buffer = new_back;
 		}
 	}
-- 
2.1.3


^ permalink raw reply related

* [PATCH 1/1] video: smscufx: Deletion of unnecessary checks before the function call "vfree"
From: SF Markus Elfring @ 2014-11-23 11:33 UTC (permalink / raw)
  To: Jean-Christophe Plagniol-Villard, Steve Glendinning,
	Tomi Valkeinen, linux-fbdev
  Cc: LKML, kernel-janitors, Julia Lawall
In-Reply-To: <5317A59D.4@users.sourceforge.net>

From: Markus Elfring <elfring@users.sourceforge.net>
Date: Sun, 23 Nov 2014 12:30:33 +0100

The vfree() function performs also input parameter validation. Thus the test
around the call is not needed.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
 drivers/video/fbdev/smscufx.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/video/fbdev/smscufx.c b/drivers/video/fbdev/smscufx.c
index d513ed6..9279e5f 100644
--- a/drivers/video/fbdev/smscufx.c
+++ b/drivers/video/fbdev/smscufx.c
@@ -1142,8 +1142,7 @@ static void ufx_free_framebuffer_work(struct work_struct *work)
 		fb_dealloc_cmap(&info->cmap);
 	if (info->monspecs.modedb)
 		fb_destroy_modedb(info->monspecs.modedb);
-	if (info->screen_base)
-		vfree(info->screen_base);
+	vfree(info->screen_base);
 
 	fb_destroy_modelist(&info->modelist);
 
@@ -1743,8 +1742,7 @@ error:
 				fb_dealloc_cmap(&info->cmap);
 			if (info->monspecs.modedb)
 				fb_destroy_modedb(info->monspecs.modedb);
-			if (info->screen_base)
-				vfree(info->screen_base);
+			vfree(info->screen_base);
 
 			fb_destroy_modelist(&info->modelist);
 
-- 
2.1.3


^ permalink raw reply related

* [PATCH 1/1] video: fbdev-SIS: Deletion of unnecessary checks before the function call "pci_dev_put"
From: SF Markus Elfring @ 2014-11-23 12:00 UTC (permalink / raw)
  To: Jean-Christophe Plagniol-Villard, Thomas Winischhofer,
	Tomi Valkeinen, linux-fbdev
  Cc: LKML, kernel-janitors, Julia Lawall
In-Reply-To: <5317A59D.4@users.sourceforge.net>

From: Markus Elfring <elfring@users.sourceforge.net>
Date: Sun, 23 Nov 2014 12:55:25 +0100

The pci_dev_put() function tests whether its argument is NULL
and then returns immediately. Thus the test around the call
is not needed.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
 drivers/video/fbdev/sis/sis_main.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/video/fbdev/sis/sis_main.c b/drivers/video/fbdev/sis/sis_main.c
index 3f12a2d..6548a3e 100644
--- a/drivers/video/fbdev/sis/sis_main.c
+++ b/drivers/video/fbdev/sis/sis_main.c
@@ -5989,7 +5989,7 @@ static int sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	if(!ivideo->sisvga_enabled) {
 		if(pci_enable_device(pdev)) {
-			if(ivideo->nbridge) pci_dev_put(ivideo->nbridge);
+			pci_dev_put(ivideo->nbridge);
 			framebuffer_release(sis_fb_info);
 			return -EIO;
 		}
@@ -6202,10 +6202,8 @@ error_0:	iounmap(ivideo->video_vbase);
 error_1:	release_mem_region(ivideo->video_base, ivideo->video_size);
 error_2:	release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
 error_3:	vfree(ivideo->bios_abase);
-		if(ivideo->lpcdev)
-			pci_dev_put(ivideo->lpcdev);
-		if(ivideo->nbridge)
-			pci_dev_put(ivideo->nbridge);
+		pci_dev_put(ivideo->lpcdev);
+		pci_dev_put(ivideo->nbridge);
 		if(!ivideo->sisvga_enabled)
 			pci_disable_device(pdev);
 		framebuffer_release(sis_fb_info);
@@ -6505,11 +6503,9 @@ static void sisfb_remove(struct pci_dev *pdev)
 
 	vfree(ivideo->bios_abase);
 
-	if(ivideo->lpcdev)
-		pci_dev_put(ivideo->lpcdev);
+	pci_dev_put(ivideo->lpcdev);
 
-	if(ivideo->nbridge)
-		pci_dev_put(ivideo->nbridge);
+	pci_dev_put(ivideo->nbridge);
 
 #ifdef CONFIG_MTRR
 	/* Release MTRR region */
-- 
2.1.3


^ permalink raw reply related

* [PATCH 1/1] video: fbdev-OMAP2: Deletion of unnecessary checks before the function call "i2c_put_ada
From: SF Markus Elfring @ 2014-11-23 13:14 UTC (permalink / raw)
  To: Jean-Christophe Plagniol-Villard, Tomi Valkeinen, linux-omap,
	linux-fbdev
  Cc: LKML, kernel-janitors, Julia Lawall
In-Reply-To: <5317A59D.4@users.sourceforge.net>

From: Markus Elfring <elfring@users.sourceforge.net>
Date: Sun, 23 Nov 2014 14:07:22 +0100

The i2c_put_adapter() function tests whether its argument is NULL
and then returns immediately. Thus the test around the call is not needed.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
 drivers/video/fbdev/omap2/displays-new/connector-dvi.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/video/fbdev/omap2/displays-new/connector-dvi.c b/drivers/video/fbdev/omap2/displays-new/connector-dvi.c
index 74de2bc..196c61a 100644
--- a/drivers/video/fbdev/omap2/displays-new/connector-dvi.c
+++ b/drivers/video/fbdev/omap2/displays-new/connector-dvi.c
@@ -262,8 +262,7 @@ static int dvic_probe_pdata(struct platform_device *pdev)
 
 	in = omap_dss_find_output(pdata->source);
 	if (in = NULL) {
-		if (ddata->i2c_adapter)
-			i2c_put_adapter(ddata->i2c_adapter);
+		i2c_put_adapter(ddata->i2c_adapter);
 
 		dev_err(&pdev->dev, "Failed to find video source\n");
 		return -EPROBE_DEFER;
@@ -352,8 +351,7 @@ static int dvic_probe(struct platform_device *pdev)
 err_reg:
 	omap_dss_put_device(ddata->in);
 
-	if (ddata->i2c_adapter)
-		i2c_put_adapter(ddata->i2c_adapter);
+	i2c_put_adapter(ddata->i2c_adapter);
 
 	return r;
 }
@@ -371,8 +369,7 @@ static int __exit dvic_remove(struct platform_device *pdev)
 
 	omap_dss_put_device(in);
 
-	if (ddata->i2c_adapter)
-		i2c_put_adapter(ddata->i2c_adapter);
+	i2c_put_adapter(ddata->i2c_adapter);
 
 	return 0;
 }
-- 
2.1.3


^ permalink raw reply related

* [PATCH 1/1] video: mx3fb: Deletion of an unnecessary check before the function call "backlight_devic
From: SF Markus Elfring @ 2014-11-23 14:20 UTC (permalink / raw)
  To: Jean-Christophe Plagniol-Villard, Tomi Valkeinen, linux-fbdev
  Cc: LKML, kernel-janitors, Julia Lawall
In-Reply-To: <5317A59D.4@users.sourceforge.net>

From: Markus Elfring <elfring@users.sourceforge.net>
Date: Sun, 23 Nov 2014 15:15:29 +0100

The backlight_device_unregister() function tests whether its argument is NULL
and then returns immediately. Thus the test around the call is not needed.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
 drivers/video/fbdev/mx3fb.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/mx3fb.c b/drivers/video/fbdev/mx3fb.c
index c645a0a..b2d2151 100644
--- a/drivers/video/fbdev/mx3fb.c
+++ b/drivers/video/fbdev/mx3fb.c
@@ -334,8 +334,7 @@ static void mx3fb_init_backlight(struct mx3fb_data *fbd)
 
 static void mx3fb_exit_backlight(struct mx3fb_data *fbd)
 {
-	if (fbd->bl)
-		backlight_device_unregister(fbd->bl);
+	backlight_device_unregister(fbd->bl);
 }
 
 static void mx3fb_dma_done(void *);
-- 
2.1.3


^ permalink raw reply related

* [PATCH 1/1] video: fbdev-MMP: Deletion of an unnecessary check before the function call "mmp_unregis
From: SF Markus Elfring @ 2014-11-23 15:00 UTC (permalink / raw)
  To: Jean-Christophe Plagniol-Villard, Tomi Valkeinen, linux-fbdev
  Cc: LKML, kernel-janitors, Julia Lawall
In-Reply-To: <5317A59D.4@users.sourceforge.net>

From: Markus Elfring <elfring@users.sourceforge.net>
Date: Sun, 23 Nov 2014 15:45:03 +0100

The mmp_unregister_path() function tests whether its argument is NULL
and then returns immediately. Thus the test around the call is not needed.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
 drivers/video/fbdev/mmp/hw/mmp_ctrl.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/mmp/hw/mmp_ctrl.c b/drivers/video/fbdev/mmp/hw/mmp_ctrl.c
index 8621a9f..3c12bd8 100644
--- a/drivers/video/fbdev/mmp/hw/mmp_ctrl.c
+++ b/drivers/video/fbdev/mmp/hw/mmp_ctrl.c
@@ -441,8 +441,7 @@ static void path_deinit(struct mmphw_path_plat *path_plat)
 	if (!path_plat)
 		return;
 
-	if (path_plat->path)
-		mmp_unregister_path(path_plat->path);
+	mmp_unregister_path(path_plat->path);
 }
 
 static int mmphw_probe(struct platform_device *pdev)
-- 
2.1.3


^ permalink raw reply related

* [PATCH 1/1] video: fbdev-VIA: Deletion of an unnecessary check before the function call "framebuffer
From: SF Markus Elfring @ 2014-11-23 15:33 UTC (permalink / raw)
  To: Florian Tobias Schandinat, Jean-Christophe Plagniol-Villard,
	Tomi Valkeinen, linux-fbdev
  Cc: LKML, kernel-janitors, Julia Lawall
In-Reply-To: <5317A59D.4@users.sourceforge.net>

From: Markus Elfring <elfring@users.sourceforge.net>
Date: Sun, 23 Nov 2014 16:30:05 +0100

The framebuffer_release() function tests whether its argument is NULL
and then returns immediately. Thus the test around the call is not needed.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
 drivers/video/fbdev/via/viafbdev.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/via/viafbdev.c b/drivers/video/fbdev/via/viafbdev.c
index 325c43c..f9718f0 100644
--- a/drivers/video/fbdev/via/viafbdev.c
+++ b/drivers/video/fbdev/via/viafbdev.c
@@ -1937,8 +1937,7 @@ out_fb1_unreg_lcd_cle266:
 out_dealloc_cmap:
 	fb_dealloc_cmap(&viafbinfo->cmap);
 out_fb1_release:
-	if (viafbinfo1)
-		framebuffer_release(viafbinfo1);
+	framebuffer_release(viafbinfo1);
 out_fb_release:
 	i2c_bus_free(viaparinfo->shared);
 	framebuffer_release(viafbinfo);
-- 
2.1.3


^ permalink raw reply related

* [PATCH 1/1] video: uvesafb: Deletion of an unnecessary check before the function call "platform_devi
From: SF Markus Elfring @ 2014-11-23 16:10 UTC (permalink / raw)
  To: Jean-Christophe Plagniol-Villard, Michal Januszewski,
	Tomi Valkeinen, linux-fbdev
  Cc: LKML, kernel-janitors, Julia Lawall
In-Reply-To: <5317A59D.4@users.sourceforge.net>

From: Markus Elfring <elfring@users.sourceforge.net>
Date: Sun, 23 Nov 2014 17:05:18 +0100

The platform_device_put() function tests whether its argument is NULL
and then returns immediately. Thus the test around the call is not needed.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
 drivers/video/fbdev/uvesafb.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c
index 509d452..17b2e8c 100644
--- a/drivers/video/fbdev/uvesafb.c
+++ b/drivers/video/fbdev/uvesafb.c
@@ -1923,8 +1923,7 @@ static int uvesafb_init(void)
 			err = -ENOMEM;
 
 		if (err) {
-			if (uvesafb_device)
-				platform_device_put(uvesafb_device);
+			platform_device_put(uvesafb_device);
 			platform_driver_unregister(&uvesafb_driver);
 			cn_del_callback(&uvesafb_cn_id);
 			return err;
-- 
2.1.3


^ permalink raw reply related

* [PATCH 1/1] backlight: lp8788: Deletion of an unnecessary check before the function call "backlight_
From: SF Markus Elfring @ 2014-11-23 16:40 UTC (permalink / raw)
  To: Bryan Wu, Jean-Christophe Plagniol-Villard, Jingoo Han, Lee Jones,
	Tomi Valkeinen, linux-fbdev
  Cc: LKML, kernel-janitors, Julia Lawall
In-Reply-To: <5317A59D.4@users.sourceforge.net>

From: Markus Elfring <elfring@users.sourceforge.net>
Date: Sun, 23 Nov 2014 17:33:08 +0100

The backlight_device_unregister() function tests whether its argument is NULL
and then returns immediately. Thus the test around the call is not needed.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
 drivers/video/backlight/lp8788_bl.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/video/backlight/lp8788_bl.c b/drivers/video/backlight/lp8788_bl.c
index d6c4f6a..24a055c 100644
--- a/drivers/video/backlight/lp8788_bl.c
+++ b/drivers/video/backlight/lp8788_bl.c
@@ -221,8 +221,7 @@ static void lp8788_backlight_unregister(struct lp8788_bl *bl)
 {
 	struct backlight_device *bl_dev = bl->bl_dev;
 
-	if (bl_dev)
-		backlight_device_unregister(bl_dev);
+	backlight_device_unregister(bl_dev);
 }
 
 static ssize_t lp8788_get_bl_ctl_mode(struct device *dev,
-- 
2.1.3


^ permalink raw reply related

* Re: [PATCH v7.1 00/19] Rework OMAP4+ HDMI audio support
From: Tomi Valkeinen @ 2014-11-24  8:18 UTC (permalink / raw)
  To: Mark Brown, Jyri Sarha
  Cc: alsa-devel, linux-fbdev, linux-omap, peter.ujfalusi,
	liam.r.girdwood
In-Reply-To: <20141121161435.GS3815@sirena.org.uk>

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

On 21/11/14 18:14, Mark Brown wrote:
> On Fri, Nov 21, 2014 at 02:35:07PM +0200, Jyri Sarha wrote:
>> On 11/21/2014 01:23 PM, Mark Brown wrote:
> 
>>> With this specific series I also need to figure out what all the video
>>> side is about (like I said earlier a lot of the patches look like
>>> they're supposed to be simple fixes for the video code not terribly
>>> closely tied to the rest of the series but none of them are getting
>>> applied) and what the end goal is beyond mechanically moving code.
> 
>> The end goal of this series is to fix OMAP HDMI audio, that got broken
>> couple of releases ago. At the same time I cleaned up the old complex scheme
>> to make the connection between the video and audio parts and allow multiple
>> HDMI devices (DSS side is not ready for this yet, but audio side is).
> 
> But in what way is it broken and how did this happen?  Why are none of

I don't have a clear answer, but it probably involves lack of use, and
buggy and hard to use implementation. Things have changed around the
original HDMI audio implementation, and it stopped working at some point.

As the original implementation was found rather lacking, and with some
fundamental issues, it was deemed better to have a fresh approach.

> the patches which look like they're supposed to be bug fixes early on in
> the series getting applied?  I had thought this was just a lack of
> interest on the video side but it seems there's some other problems
> since the series has apparently been discussed off-list and still it's
> just as big as it was initially.

The whole series is about HDMI audio, not video.

The main HDMI driver resides in the fbdev directory, as the video side
is the "master" here, and it contains the code to access the registers
(including audio related registers). The sound/ part in this series acts
as a logic between the asoc and the low level HDMI driver.

This series only touch the parts about HDMI audio, so the fixes early on
don't really fix anything without the rest of the series (as the current
HDMI audio doesn't work).

And in any case, I don't like applying individual patches from a series.
Usually that just complicates things. If I would apply some of the early
patches to fbdev, then this series would no longer work on plain
mainline kernel, and would instead depend on fbdev tree. The situation
would be ever worse if you'd also pick some of the audio patches to
sound tree, creating a dependency to two subsystem trees.

So if there's no particular important reason to pick patches from a
series, I rather keep it as a whole to simplify merging and testing.

 Tomi



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

^ permalink raw reply

* Re: [PATCH v7.1 00/19] Rework OMAP4+ HDMI audio support
From: Tomi Valkeinen @ 2014-11-24  8:48 UTC (permalink / raw)
  To: Mark Brown, Jyri Sarha
  Cc: alsa-devel, linux-fbdev, linux-omap, peter.ujfalusi,
	liam.r.girdwood
In-Reply-To: <20141121163815.GT3815@sirena.org.uk>

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

On 21/11/14 18:38, Mark Brown wrote:
> On Fri, Nov 21, 2014 at 02:10:11PM +0200, Jyri Sarha wrote:
> 
>> OMAP HDMI audio is fundamentally different to the case on Armada or on BBB.
>> In omap the whole HDMI IP is integrated to the SoC and there really is no
>> codec in the ASoC sense. The the cpu-dai transmits the audio directly to
>> hdmi wire and there is no i2s bus involved. So this case should not be mixed
>> with the patches Jean-Francois working on. The code is also orthogonal in
>> that sense that the latest omap-hdmi-audio uses the generic dymmy codec.
> 
> The discussion seemed to be about what to do with unplugged connections
> which isn't what you're talking about there and does seem like an area
> where we should at least be aiming for common behaviour even if not a
> common implementation.
> 
> There's also all the stuff about parsing EDIDs for capabilities which
> would seem to be related to that but seems to have gone off into the
> weeds.

I agree all these should be studied and worked further. However, I would
still like to merge this series in the next merge window:

a) The series does fix the OMAP HDMI audio, so that users can actually
use it.

b) The series does make the driver model much better, so that I can
actually be bothered to keep it enabled (earlier, even when it more or
less worked, it was too much hassle when doing development using modules).

 Tomi



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

^ permalink raw reply

* Re: [PATCH 1/1] backlight: lp8788: Deletion of an unnecessary check before the function call "backli
From: Lee Jones @ 2014-11-24 10:09 UTC (permalink / raw)
  To: SF Markus Elfring
  Cc: Bryan Wu, Jean-Christophe Plagniol-Villard, Jingoo Han,
	Tomi Valkeinen, linux-fbdev, LKML, kernel-janitors, Julia Lawall
In-Reply-To: <54720DEB.4060109@users.sourceforge.net>

On Sun, 23 Nov 2014, SF Markus Elfring wrote:

> From: Markus Elfring <elfring@users.sourceforge.net>
> Date: Sun, 23 Nov 2014 17:33:08 +0100

What format is this?

Can you use `git format-patch` and `git send-email` instead please?
 
> The backlight_device_unregister() function tests whether its argument is NULL
> and then returns immediately. Thus the test around the call is not needed.
> 
> This issue was detected by using the Coccinelle software.
> 
> Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
> ---
>  drivers/video/backlight/lp8788_bl.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/video/backlight/lp8788_bl.c b/drivers/video/backlight/lp8788_bl.c
> index d6c4f6a..24a055c 100644
> --- a/drivers/video/backlight/lp8788_bl.c
> +++ b/drivers/video/backlight/lp8788_bl.c
> @@ -221,8 +221,7 @@ static void lp8788_backlight_unregister(struct lp8788_bl *bl)
>  {
>  	struct backlight_device *bl_dev = bl->bl_dev;
>  
> -	if (bl_dev)
> -		backlight_device_unregister(bl_dev);
> +	backlight_device_unregister(bl_dev);
>  }
>  
>  static ssize_t lp8788_get_bl_ctl_mode(struct device *dev,

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* Re: [PATCH 1/1] backlight: lp8788: Deletion of an unnecessary check before the function call "backli
From: Lee Jones @ 2014-11-24 10:10 UTC (permalink / raw)
  To: SF Markus Elfring
  Cc: Bryan Wu, Jean-Christophe Plagniol-Villard, Jingoo Han,
	Tomi Valkeinen, linux-fbdev, LKML, kernel-janitors, Julia Lawall
In-Reply-To: <54720DEB.4060109@users.sourceforge.net>

On Sun, 23 Nov 2014, SF Markus Elfring wrote:

> From: Markus Elfring <elfring@users.sourceforge.net>
> Date: Sun, 23 Nov 2014 17:33:08 +0100
> 
> The backlight_device_unregister() function tests whether its argument is NULL
> and then returns immediately. Thus the test around the call is not needed.

Also the $SUBJECT should be less than 75 chars.

> This issue was detected by using the Coccinelle software.
> 
> Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
> ---
>  drivers/video/backlight/lp8788_bl.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/video/backlight/lp8788_bl.c b/drivers/video/backlight/lp8788_bl.c
> index d6c4f6a..24a055c 100644
> --- a/drivers/video/backlight/lp8788_bl.c
> +++ b/drivers/video/backlight/lp8788_bl.c
> @@ -221,8 +221,7 @@ static void lp8788_backlight_unregister(struct lp8788_bl *bl)
>  {
>  	struct backlight_device *bl_dev = bl->bl_dev;
>  
> -	if (bl_dev)
> -		backlight_device_unregister(bl_dev);
> +	backlight_device_unregister(bl_dev);
>  }
>  
>  static ssize_t lp8788_get_bl_ctl_mode(struct device *dev,

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* [PATCH 0/4] LS1021A: Add dcfb framebuffer driver support.
From: Xiubo Li @ 2014-11-24 10:20 UTC (permalink / raw)
  To: linux-arm-kernel

Framebuffer driver for the Freescale SoC Display Controller.

Xiubo Li (4):
  video: fsl-dcfb: Add dcfb framebuffer driver for LS1021A platform
  video: fsl-dcfb: Add devicetree binding support
  ARM: ls1021a: dtsi: Add dt node support for dcfb.
  ARM: ls1021a: dts: Add and enable dt node for dcfb.

 .../devicetree/bindings/video/fsl,dcfb.txt         |  52 ++
 arch/arm/boot/dts/ls1021a-twr.dts                  |  26 +
 arch/arm/boot/dts/ls1021a.dtsi                     |  10 +
 drivers/video/fbdev/Kconfig                        |  19 +
 drivers/video/fbdev/Makefile                       |   1 +
 drivers/video/fbdev/fsl-dcfb.c                     | 811 +++++++++++++++++++++
 6 files changed, 919 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/fsl,dcfb.txt
 create mode 100644 drivers/video/fbdev/fsl-dcfb.c

-- 
2.1.0.27.g96db324


^ permalink raw reply

* [PATCH 1/4] video: fsl-dcfb: Add dcfb framebuffer driver for LS1021A platform
From: Xiubo Li @ 2014-11-24 10:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1416824454-28156-1-git-send-email-Li.Xiubo@freescale.com>

The Display Controller module is a system master that fetches graphics
stored in internal/external memory and displays them on a TFT LCD panel.
A wide range of panel sizes is supported and the timing of the interface
signals is configurable.

The dcfb has these features:
o Full RGB888 output to TFT LCD panel.
o Optional output to system memory dependent on implementation.
o Supports Programmable panel size upto a maximum of 2032x2047. The actual
  resolution supported depends upon the pixel clock and bus bandwidth
  available.
o Gamma correction with 8-bit resolution on each color component.
o Dedicated memory blocks to store a cursor and Color Look Up Tables(CLUTs).
o Temporal Dithering.

Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com>
---
 drivers/video/fbdev/Kconfig    |  19 +
 drivers/video/fbdev/Makefile   |   1 +
 drivers/video/fbdev/fsl-dcfb.c | 811 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 831 insertions(+)
 create mode 100644 drivers/video/fbdev/fsl-dcfb.c

diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 1f0298e..945649a0 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -1965,6 +1965,25 @@ config FB_MBX_DEBUG
 
          If unsure, say N.
 
+config FB_FSL_DCFB
+	tristate "Freescale Display Control Framebuffer Support"
+	depends on FB
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_MODE_HELPERS
+	select VIDEOMODE_HELPERS
+	select REGMAP_MMIO
+	---help---
+	  Framebuffer driver for the Freescale SoC Display Control.
+
+	  This driver is also available as a module ( = code which can be
+	  inserted and removed from the running kernel whenever you want).
+	  If you want to compile it as a module, say M here and read
+	  <file:Documentation/kbuild/modules.txt>.
+
+	  If unsure, say N.
+
 config FB_FSL_DIU
 	tristate "Freescale DIU framebuffer support"
 	depends on FB && FSL_SOC
diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile
index 1979aff..9015138 100644
--- a/drivers/video/fbdev/Makefile
+++ b/drivers/video/fbdev/Makefile
@@ -109,6 +109,7 @@ obj-$(CONFIG_FB_SH7760)		  += sh7760fb.o
 obj-$(CONFIG_FB_IMX)              += imxfb.o
 obj-$(CONFIG_FB_S3C)		  += s3c-fb.o
 obj-$(CONFIG_FB_S3C2410)	  += s3c2410fb.o
+obj-$(CONFIG_FB_FSL_DCFB)	  += fsl-dcfb.o
 obj-$(CONFIG_FB_FSL_DIU)	  += fsl-diu-fb.o
 obj-$(CONFIG_FB_COBALT)           += cobalt_lcdfb.o
 obj-$(CONFIG_FB_IBM_GXT4500)	  += gxt4500.o
diff --git a/drivers/video/fbdev/fsl-dcfb.c b/drivers/video/fbdev/fsl-dcfb.c
new file mode 100644
index 0000000..d0dd9fc
--- /dev/null
+++ b/drivers/video/fbdev/fsl-dcfb.c
@@ -0,0 +1,811 @@
+/*
+ * Copyright 2012-2014 Freescale Semiconductor, Inc.
+ *
+ * Freescale Dispaly Controller Framebuffer Driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/fb.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <video/of_display_timing.h>
+#include <video/videomode.h>
+
+#define FSL_SCFG_CTRL		0x28
+#define FSL_SCFG_PIXEL_EN	BIT(31)
+
+#define FSL_DCFB_MODE		0x10
+#define FSL_DCFB_BGND		0x14
+#define FSL_DCFB_FIX_SIZE	0x18
+#define FSL_DCFB_HSYN		0x1c
+#define FSL_DCFB_VSYN		0x20
+#define FSL_DCFB_SP		0x24
+#define FSL_DCFB_TS		0x28
+#define FSL_DCFB_DIV_RATIO	0x54
+#define FSL_DCFB_UPDATE		0xcc
+#define FSL_DCFB_VAR_SIZE	0x200
+#define FSL_DCFB_POS		0x204
+#define FSL_DCFB_BASE		0x208
+#define FSL_DCFB_CTRL		0x20c
+#define FSL_DCFB_CKMAX		0x210
+#define FSL_DCFB_CKMIN		0x214
+#define FSL_DCFB_FCOLOR		0x21c
+#define FSL_DCFB_BCOLOR		0x220
+#define FSL_DCFB_SKIP		0x224
+#define FSL_DCFB_MAX		0x300
+
+#define FSL_DCFB_HSYN_BP(x)	((x) << 22)
+#define FSL_DCFB_HSYN_PW(x)	((x) << 11)
+#define FSL_DCFB_HSYN_FP(x)	(x)
+#define FSL_DCFB_VSYN_BP(x)	((x) << 22)
+#define FSL_DCFB_VSYN_PW(x)	((x) << 11)
+#define FSL_DCFB_VSYN_FP(x)	(x)
+
+#define FSL_DCFB_SP_VS		BIT(1)
+#define FSL_DCFB_SP_HS		BIT(0)
+
+#define FSL_DCFB_TS_LBV(x)	((x) << 16)
+#define FSL_DCFB_TS_OBH(x)	((x) << 8)
+#define FSL_DCFB_TS_OBL(x)	(x)
+
+#define FSL_DCFB_UPDATE_MODE	BIT(31)
+#define FSL_DCFB_UPDATE_READREG	BIT(30)
+
+#define FSL_DCFB_VAR_SIZE_H(x)	((x) << 16)
+#define FSL_DCFB_VAR_SIZE_W(x)	(x)
+
+#define FSL_DCFB_POSY(x)	((x) << 16)
+#define FSL_DCFB_POSX(x)	(x)
+
+#define FSL_DCFB_CTRL_EN	BIT(31)
+#define FSL_DCFB_CTRL_TILE_EN	BIT(30)
+#define FSL_DCFB_CTRL_DATA_SEL_CLUT	BIT(29)
+#define FSL_DCFB_CTRL_SAFETY_EN	BIT(28)
+#define FSL_DCFB_CTRL_TRANS(x)	((x) << 20)
+#define FSL_DCFB_CTRL_BPP(x)	((x) << 16)
+#define FSL_DCFB_CTRL_RLE_EN	BIT(15)
+#define FSL_DCFB_CTRL_LUOFFS(x)	((x) << 4)
+#define FSL_DCFB_CTRL_BB_ON	BIT(2)
+
+#define FSL_DCFB_CKMAX_R(x)	((x) << 16)
+#define FSL_DCFB_CKMAX_G(x)	((x) << 8)
+#define FSL_DCFB_CKMAX_B(x)	(x)
+
+#define FSL_DCFB_CKMIN_R(x)	((x) << 16)
+#define FSL_DCFB_CKMIN_G(x)	((x) << 8)
+#define FSL_DCFB_CKMIN_B(x)	(x)
+
+#define FSL_DCFB_TILE_SIZE_W(x)	((x) << 16)
+#define FSL_DCFB_TILE_SIZE_H(x)	(x)
+
+#define FSL_DCFB_FCOLOR_OFF(x)	(x)
+#define FSL_DCFB_BCOLOR_OFF(x)	(x)
+
+#define FSL_DCFB_MODE_BITER(x)	((x) << 20)
+#define FSL_DCFB_MODE_RASTER_EN	BIT(14)
+#define FSL_DCFB_MODE_MODE(x)	(x)
+#define FSL_DCFB_MODE_MODE_MASK	0x03
+
+#define FSL_DCFB_BGND_R(x)	((x) << 16)
+#define FSL_DCFB_BGND_G(x)	((x) << 8)
+#define FSL_DCFB_BGND_B(x)	(x)
+
+#define FSL_DCFB_FIX_SIZE_Y(x)	((x) << 16)
+#define FSL_DCFB_FIX_SIZE_X(x)	(x)
+
+enum fsl_dcfb_fmt {
+	FSL_DCFB_RGB565 = 4,
+	FSL_DCFB_RGB888,
+	FSL_DCFB_ARGB8888,
+};
+
+enum fsl_dcfb_mode {
+	FSL_DCFB_MOD_OFF = 0,
+	FSL_DCFB_MOD_NORMAL,
+	FSL_DCFB_MOD_TEST,
+	FSL_DCFB_MOD_COLORBAR,
+};
+
+struct fsl_dcfb_mfb_info {
+	unsigned long pseudo_palette[16];
+	unsigned int count;
+	struct fsl_dcfb_fb_private *parent;
+};
+
+struct fsl_dcfb_fb_private {
+	struct fb_info *fsl_dcfb_info;
+	struct device *dev;
+	struct regmap *regmap;
+	struct clk *clk;
+};
+
+static int fsl_dcfb_get_bpp(unsigned int bits_per_pixel)
+{
+	int bpp;
+
+	switch (bits_per_pixel) {
+	case 16:
+		bpp = FSL_DCFB_RGB565;
+		break;
+	case 24:
+		bpp = FSL_DCFB_RGB888;
+		break;
+	case 32:
+		bpp = FSL_DCFB_ARGB8888;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return bpp;
+}
+
+static int fsl_dcfb_set_panel(struct fb_info *info)
+{
+	struct fb_var_screeninfo *var = &info->var;
+	struct fsl_dcfb_mfb_info *mfbi = info->par;
+	struct fsl_dcfb_fb_private *dcfb = mfbi->parent;
+	int bpp;
+
+	regmap_write(dcfb->regmap, FSL_DCFB_VAR_SIZE,
+		     FSL_DCFB_VAR_SIZE_H(var->yres) |
+		     FSL_DCFB_VAR_SIZE_W(var->xres));
+	regmap_write(dcfb->regmap, FSL_DCFB_POS,
+		     FSL_DCFB_POSY(0) | FSL_DCFB_POSX(0));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_BASE, info->fix.smem_start);
+
+	bpp = fsl_dcfb_get_bpp(var->bits_per_pixel);
+	if (bpp < 0) {
+		dev_err(dcfb->dev, "unsupported color depth: %u\n",
+				var->bits_per_pixel);
+		return bpp;
+	}
+
+	regmap_write(dcfb->regmap, FSL_DCFB_CTRL, FSL_DCFB_CTRL_EN |
+		     FSL_DCFB_CTRL_TRANS(0xFF) | FSL_DCFB_CTRL_BPP(bpp));
+	regmap_write(dcfb->regmap, FSL_DCFB_CKMAX, FSL_DCFB_CKMAX_R(0xFF) |
+		     FSL_DCFB_CKMAX_G(0xFF) | FSL_DCFB_CKMAX_B(0xFF));
+	regmap_write(dcfb->regmap, FSL_DCFB_CKMIN, FSL_DCFB_CKMIN_R(0) |
+		     FSL_DCFB_CKMIN_G(0) | FSL_DCFB_CKMIN_B(0));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_FCOLOR, FSL_DCFB_FCOLOR_OFF(0));
+	regmap_write(dcfb->regmap, FSL_DCFB_BCOLOR, FSL_DCFB_BCOLOR_OFF(0));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_UPDATE, FSL_DCFB_UPDATE_READREG);
+
+	return 0;
+}
+
+static int fsl_dcfb_reset_panel(struct fsl_dcfb_fb_private *dcfb)
+{
+	regmap_write(dcfb->regmap, FSL_DCFB_VAR_SIZE, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_POS, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_BASE, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_CTRL, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_CKMAX, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_CKMIN, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_FCOLOR, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_BCOLOR, 0x0);
+	regmap_write(dcfb->regmap, FSL_DCFB_SKIP, 0x0);
+
+	regmap_write(dcfb->regmap, FSL_DCFB_UPDATE, FSL_DCFB_UPDATE_READREG);
+
+	return 0;
+}
+
+static void fsl_dcfb_modeset(struct fsl_dcfb_fb_private *dcfb,
+			     enum fsl_dcfb_mode mode)
+{
+	regmap_update_bits(dcfb->regmap, FSL_DCFB_MODE,
+			   FSL_DCFB_MODE_MODE_MASK,
+			   FSL_DCFB_MODE_MODE(mode));
+}
+
+static int fsl_dcfb_check_var(struct fb_var_screeninfo *var,
+		struct fb_info *info)
+{
+	struct fsl_dcfb_mfb_info *mfbi = info->par;
+	struct fsl_dcfb_fb_private *dcfb = mfbi->parent;
+
+	if (var->xres_virtual < var->xres)
+		var->xres_virtual = var->xres;
+	if (var->yres_virtual < var->yres)
+		var->yres_virtual = var->yres;
+
+	if (var->xoffset + info->var.xres > info->var.xres_virtual)
+		var->xoffset = info->var.xres_virtual - info->var.xres;
+
+	if (var->yoffset + info->var.yres > info->var.yres_virtual)
+		var->yoffset = info->var.yres_virtual - info->var.yres;
+
+	switch (var->bits_per_pixel) {
+	case 16:
+		var->red.length = 5;
+		var->red.offset = 11;
+		var->red.msb_right = 0;
+
+		var->green.length = 6;
+		var->green.offset = 5;
+		var->green.msb_right = 0;
+
+		var->blue.length = 5;
+		var->blue.offset = 0;
+		var->blue.msb_right = 0;
+
+		var->transp.length = 0;
+		var->transp.offset = 0;
+		var->transp.msb_right = 0;
+		break;
+	case 24:
+		var->red.length = 8;
+		var->red.offset = 16;
+		var->red.msb_right = 0;
+
+		var->green.length = 8;
+		var->green.offset = 8;
+		var->green.msb_right = 0;
+
+		var->blue.length = 8;
+		var->blue.offset = 0;
+		var->blue.msb_right = 0;
+
+		var->transp.length = 0;
+		var->transp.offset = 0;
+		var->transp.msb_right = 0;
+		break;
+	case 32:
+		var->red.length = 8;
+		var->red.offset = 16;
+		var->red.msb_right = 0;
+
+		var->green.length = 8;
+		var->green.offset = 8;
+		var->green.msb_right = 0;
+
+		var->blue.length = 8;
+		var->blue.offset = 0;
+		var->blue.msb_right = 0;
+
+		var->transp.length = 8;
+		var->transp.offset = 24;
+		var->transp.msb_right = 0;
+		break;
+	default:
+		dev_err(dcfb->dev, "unsupported color depth: %u\n",
+			var->bits_per_pixel);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int fsl_dcfb_alloc_mem(struct fb_info *info)
+{
+	struct fsl_dcfb_mfb_info *mfbi = info->par;
+	struct fsl_dcfb_fb_private *dcfb = mfbi->parent;
+	u32 smem_len = info->fix.line_length * info->var.yres_virtual;
+
+	info->fix.smem_len = smem_len;
+
+	info->screen_base = dma_alloc_writecombine(info->device,
+		info->fix.smem_len, (dma_addr_t *)&info->fix.smem_start,
+		GFP_KERNEL);
+	if (!info->screen_base) {
+		dev_err(dcfb->dev, "unable to allocate fb memory\n");
+		return -ENOMEM;
+	}
+
+	memset(info->screen_base, 0, info->fix.smem_len);
+
+	return 0;
+}
+
+static void fsl_dcfb_free_mem(struct fb_info *info)
+{
+	if (!info->screen_base)
+		return;
+
+	dma_free_writecombine(info->device, info->fix.smem_len,
+		info->screen_base, info->fix.smem_start);
+
+	info->screen_base = NULL;
+	info->fix.smem_start = 0;
+	info->fix.smem_len = 0;
+}
+
+static int fsl_dcfb_set_par(struct fb_info *info)
+{
+	struct fb_var_screeninfo *var = &info->var;
+	struct fb_fix_screeninfo *fix = &info->fix;
+	struct fsl_dcfb_mfb_info *mfbi = info->par;
+	struct fsl_dcfb_fb_private *dcfb = mfbi->parent;
+	unsigned int div, len;
+
+	fix->type = FB_TYPE_PACKED_PIXELS;
+	fix->accel = FB_ACCEL_NONE;
+	fix->visual = FB_VISUAL_TRUECOLOR;
+	fix->xpanstep = fix->ypanstep = 1;
+
+	fix->line_length = var->xres_virtual * var->bits_per_pixel / 8;
+	len = info->var.yres_virtual * info->fix.line_length;
+	if (len != info->fix.smem_len) {
+		if (info->fix.smem_start)
+			fsl_dcfb_free_mem(info);
+
+		if (fsl_dcfb_alloc_mem(info)) {
+			dev_err(dcfb->dev, "unable to allocate FB memory\n");
+			return -ENOMEM;
+		}
+	}
+
+	div = KHZ2PICOS(clk_get_rate(dcfb->clk) / 1000);
+	regmap_write(dcfb->regmap, FSL_DCFB_DIV_RATIO,
+		     info->var.pixclock / div);
+
+	regmap_write(dcfb->regmap, FSL_DCFB_FIX_SIZE,
+		     FSL_DCFB_FIX_SIZE_Y(var->yres) |
+		     FSL_DCFB_FIX_SIZE_X(var->xres / 16));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_HSYN,
+		     FSL_DCFB_HSYN_BP(var->left_margin) |
+		     FSL_DCFB_HSYN_PW(var->hsync_len) |
+		     FSL_DCFB_HSYN_FP(var->right_margin));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_VSYN,
+		     FSL_DCFB_VSYN_BP(var->upper_margin) |
+		     FSL_DCFB_VSYN_PW(var->vsync_len) |
+		     FSL_DCFB_VSYN_FP(var->lower_margin));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_SP,
+		     FSL_DCFB_SP_VS | FSL_DCFB_SP_HS);
+
+	regmap_write(dcfb->regmap, FSL_DCFB_BGND, FSL_DCFB_BGND_R(0) |
+		     FSL_DCFB_BGND_G(0) | FSL_DCFB_BGND_B(0));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_MODE,
+		     FSL_DCFB_MODE_BITER(1) | FSL_DCFB_MODE_RASTER_EN);
+
+	regmap_write(dcfb->regmap, FSL_DCFB_TS, FSL_DCFB_TS_LBV(0x03) |
+		     FSL_DCFB_TS_OBH(0x78) | FSL_DCFB_TS_OBL(0x0A));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_UPDATE, FSL_DCFB_UPDATE_READREG);
+
+	fsl_dcfb_modeset(dcfb, FSL_DCFB_MOD_NORMAL);
+	fsl_dcfb_set_panel(info);
+
+	return 0;
+}
+
+#define CNVT_TOHW(val, width) ((((val) << (width)) + 0x7FFF - (val)) >> 16)
+static int fsl_dcfb_setcolreg(unsigned regno, unsigned red, unsigned green,
+			      unsigned blue, unsigned transp,
+			      struct fb_info *info)
+{
+	int ret = 1;
+
+	/*
+	 * If greyscale is true, then we convert the RGB value
+	 * to greyscale no matter what visual we are using.
+	 */
+	if (info->var.grayscale)
+		red = green = blue = (19595 * red + 38470 * green +
+				      7471 * blue) >> 16;
+
+	switch (info->fix.visual) {
+	case FB_VISUAL_TRUECOLOR:
+		if (regno < 16) {
+			u32 *pal = info->pseudo_palette;
+			u32 value;
+
+			red = CNVT_TOHW(red, info->var.red.length);
+			green = CNVT_TOHW(green, info->var.green.length);
+			blue = CNVT_TOHW(blue, info->var.blue.length);
+			transp = CNVT_TOHW(transp, info->var.transp.length);
+
+			value = (red << info->var.red.offset) |
+				(green << info->var.green.offset) |
+				(blue << info->var.blue.offset) |
+				(transp << info->var.transp.offset);
+
+			pal[regno] = value;
+			ret = 0;
+		}
+		break;
+	case FB_VISUAL_STATIC_PSEUDOCOLOR:
+	case FB_VISUAL_PSEUDOCOLOR:
+		break;
+	}
+
+	return ret;
+}
+#undef CNVT_TOHW
+
+static int fsl_dcfb_pan_display(struct fb_var_screeninfo *var,
+			     struct fb_info *info)
+{
+	struct fsl_dcfb_mfb_info *mfbi = info->par;
+	struct fsl_dcfb_fb_private *dcfb = mfbi->parent;
+	unsigned long addr;
+	int offset;
+
+	if ((info->var.xoffset = var->xoffset) &&
+	    (info->var.yoffset = var->yoffset))
+		return 0;
+
+	if ((var->xoffset + info->var.xres) > info->var.xres_virtual
+	    || (var->yoffset + info->var.yres) > info->var.yres_virtual)
+		return -EINVAL;
+
+	info->var.xoffset = var->xoffset;
+	info->var.yoffset = var->yoffset;
+
+	if (var->vmode & FB_VMODE_YWRAP)
+		info->var.vmode |= FB_VMODE_YWRAP;
+	else
+		info->var.vmode &= ~FB_VMODE_YWRAP;
+
+	offset = (info->var.yoffset * info->var.xres_virtual);
+	offset += info->var.xoffset;
+	addr = info->fix.smem_start +
+		(offset * (info->var.bits_per_pixel >> 3));
+
+	regmap_write(dcfb->regmap, FSL_DCFB_BASE, addr);
+	regmap_write(dcfb->regmap, FSL_DCFB_UPDATE, FSL_DCFB_UPDATE_READREG);
+
+	return 0;
+}
+
+static int fsl_dcfb_blank(int blank_mode, struct fb_info *info)
+{
+	struct fsl_dcfb_mfb_info *mfbi = info->par;
+	struct fsl_dcfb_fb_private *dcfb = mfbi->parent;
+
+	switch (blank_mode) {
+	case FB_BLANK_VSYNC_SUSPEND:
+	case FB_BLANK_HSYNC_SUSPEND:
+	case FB_BLANK_NORMAL:
+		fsl_dcfb_reset_panel(dcfb);
+		break;
+	case FB_BLANK_POWERDOWN:
+		fsl_dcfb_modeset(dcfb, FSL_DCFB_MOD_OFF);
+		break;
+	case FB_BLANK_UNBLANK:
+		fsl_dcfb_set_panel(info);
+		break;
+	}
+
+	return 0;
+}
+
+static int fsl_dcfb_open(struct fb_info *info, int user)
+{
+	struct fsl_dcfb_mfb_info *mfbi = info->par;
+	int ret = 0;
+
+	mfbi->count++;
+	if (mfbi->count = 1) {
+		fsl_dcfb_check_var(&info->var, info);
+		ret = fsl_dcfb_set_par(info);
+		if (ret < 0)
+			mfbi->count--;
+	}
+
+	return ret;
+}
+
+static int fsl_dcfb_release(struct fb_info *info, int user)
+{
+	struct fsl_dcfb_mfb_info *mfbi = info->par;
+	struct fsl_dcfb_fb_private *dcfb = mfbi->parent;
+	int ret = 0;
+
+	mfbi->count--;
+	if (mfbi->count = 0)
+		ret = fsl_dcfb_reset_panel(dcfb);
+
+	return ret;
+}
+
+static struct fb_ops fsl_dcfb_ops = {
+	.owner = THIS_MODULE,
+	.fb_check_var = fsl_dcfb_check_var,
+	.fb_set_par = fsl_dcfb_set_par,
+	.fb_setcolreg = fsl_dcfb_setcolreg,
+	.fb_blank = fsl_dcfb_blank,
+	.fb_pan_display = fsl_dcfb_pan_display,
+	.fb_fillrect = cfb_fillrect,
+	.fb_copyarea = cfb_copyarea,
+	.fb_imageblit = cfb_imageblit,
+	.fb_open = fsl_dcfb_open,
+	.fb_release = fsl_dcfb_release,
+};
+
+static int fsl_dcfb_init_fbinfo(struct fb_info *info)
+{
+	struct fsl_dcfb_mfb_info *mfbi = info->par;
+	struct fb_var_screeninfo *var = &info->var;
+	struct fsl_dcfb_fb_private *dcfb = mfbi->parent;
+	struct device_node *np = dcfb->dev->of_node;
+	struct device_node *dnp, *tnp;
+	struct display_timings *timings;
+	int i, ret;
+
+	dnp = of_parse_phandle(np, "display", 0);
+	if (!dnp) {
+		dev_err(dcfb->dev, "failed to find \"display\" phandle.\n");
+		return -ENODEV;
+	}
+
+	ret = of_property_read_u32(dnp, "bits-per-pixel",
+				   &var->bits_per_pixel);
+	if (ret < 0) {
+		dev_err(dcfb->dev, "failed to get \"bits-per-pixel\" property.\n");
+		goto put_dnp;
+	}
+
+	timings = of_get_display_timings(dnp);
+	if (!timings) {
+		dev_err(dcfb->dev, "failed to get display timings\n");
+		return -ENODEV;
+		goto put_dnp;
+	}
+
+	tnp = of_find_node_by_name(dnp, "display-timings");
+	if (!tnp) {
+		dev_err(dcfb->dev, "failed to find \"display-timings\" node\n");
+		return -ENODEV;
+		goto put_dnp;
+	}
+
+	for (i = 0; i < of_get_child_count(tnp); i++) {
+		struct videomode vm;
+		struct fb_videomode fb_vm;
+
+		ret = videomode_from_timings(timings, &vm, i);
+		if (ret < 0)
+			goto put_tnp;
+
+		ret = fb_videomode_from_videomode(&vm, &fb_vm);
+		if (ret < 0)
+			goto put_tnp;
+
+		fb_add_videomode(&fb_vm, &info->modelist);
+	}
+
+put_tnp:
+	of_node_put(tnp);
+put_dnp:
+	of_node_put(dnp);
+
+	return ret;
+}
+
+static const struct regmap_config fsl_scfg_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+
+	.max_register = FSL_SCFG_CTRL,
+};
+
+static int scfg_config(struct fsl_dcfb_fb_private *dcfb, struct device_node *np)
+{
+	struct device_node *snp;
+	struct platform_device *pdev;
+	struct resource *res;
+	void __iomem *base;
+	struct regmap *regmap;
+	int ret = 0;
+
+	snp = of_parse_phandle(np, "scfg-controller", 0);
+	if (!snp)
+		return -ENODEV;
+
+	pdev = of_find_device_by_node(snp);
+	if (!pdev) {
+		ret = -ENODEV;
+		goto put_snp;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		ret = -ENODEV;
+		goto put_snp;
+	}
+
+	base = ioremap(res->start, SZ_4K);
+	if (IS_ERR(base)) {
+		dev_err(&pdev->dev, "could not ioremap scfg resource\n");
+		ret = PTR_ERR(base);
+		goto put_snp;
+	}
+
+	regmap = regmap_init_mmio(&pdev->dev, base,
+				  &fsl_scfg_regmap_config);
+	if (IS_ERR(regmap)) {
+		dev_err(&pdev->dev, "regmap init failed\n");
+		ret = PTR_ERR(regmap);
+		goto ioremap;
+	}
+
+	regmap_write(regmap, FSL_SCFG_CTRL, FSL_SCFG_PIXEL_EN);
+
+	regmap_exit(regmap);
+ioremap:
+	iounmap(base);
+put_snp:
+	of_node_put(snp);
+
+	return ret;
+}
+
+static int fsl_dcfb_dev_init(struct device_node *np,
+			     struct fsl_dcfb_fb_private *dcfb)
+{
+	int ret;
+
+	ret = scfg_config(dcfb, np);
+	if (ret) {
+		dev_err(dcfb->dev, "could not config scfg\n");
+		return -EINVAL;
+	}
+
+	return fsl_dcfb_reset_panel(dcfb);
+}
+
+static const struct regmap_config fsl_dcfb_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+
+	.max_register = FSL_DCFB_MAX,
+};
+
+static int fsl_dcfb_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct fb_modelist *modelist;
+	struct fsl_dcfb_fb_private *dcfb;
+	struct fsl_dcfb_mfb_info *mfbi;
+	struct fb_info *info;
+	struct resource *res;
+	void __iomem *base;
+	int ret = 0;
+
+	dcfb = devm_kzalloc(&pdev->dev,
+		sizeof(struct fsl_dcfb_fb_private), GFP_KERNEL);
+	if (!dcfb)
+		return -ENOMEM;
+
+	dcfb->dev = &pdev->dev;
+	dev_set_drvdata(&pdev->dev, dcfb);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "could not get memory IO resource\n");
+		return -ENODEV;
+	}
+
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base)) {
+		dev_err(&pdev->dev, "could not ioremap resource\n");
+		return PTR_ERR(base);
+	}
+
+	dcfb->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
+				NULL, base, &fsl_dcfb_regmap_config);
+	if (IS_ERR(dcfb->regmap)) {
+		dev_err(&pdev->dev, "regmap init failed\n");
+		return PTR_ERR(dcfb->regmap);
+	}
+
+	dcfb->clk = devm_clk_get(&pdev->dev, "dcfb");
+	if (IS_ERR(dcfb->clk)) {
+		ret = PTR_ERR(dcfb->clk);
+		dev_err(&pdev->dev, "could not get clock\n");
+		return -EINVAL;
+	}
+	clk_prepare_enable(dcfb->clk);
+
+	fsl_dcfb_dev_init(np, dcfb);
+
+	dcfb->fsl_dcfb_info +		framebuffer_alloc(sizeof(struct fsl_dcfb_mfb_info), &pdev->dev);
+	if (!dcfb->fsl_dcfb_info) {
+		ret = -ENOMEM;
+		goto err_clk;
+	}
+
+	dcfb->fsl_dcfb_info->fix.smem_start = 0;
+
+	mfbi = dcfb->fsl_dcfb_info->par;
+	mfbi->count = 0,
+	mfbi->parent = dcfb;
+
+	info = dcfb->fsl_dcfb_info;
+	info->var.activate = FB_ACTIVATE_NOW;
+	info->fbops = &fsl_dcfb_ops;
+	info->flags = FBINFO_FLAG_DEFAULT;
+	info->pseudo_palette = &mfbi->pseudo_palette;
+
+	ret = fb_alloc_cmap(&info->cmap, 16, 0);
+	if (ret) {
+		ret = -ENOMEM;
+		goto err_mem;
+	}
+
+	INIT_LIST_HEAD(&info->modelist);
+
+	ret = fsl_dcfb_init_fbinfo(info);
+	if (ret)
+		goto err_cmap;
+
+	modelist = list_first_entry(&info->modelist,
+			struct fb_modelist, list);
+	fb_videomode_to_var(&info->var, &modelist->mode);
+
+	fsl_dcfb_check_var(&info->var, info);
+	ret = register_framebuffer(info);
+	if (ret < 0) {
+		dev_err(dcfb->dev, "failed to register framebuffer device\n");
+		goto err_cmap;
+	}
+	goto out;
+
+err_cmap:
+	fb_dealloc_cmap(&info->cmap);
+err_mem:
+	framebuffer_release(dcfb->fsl_dcfb_info);
+err_clk:
+	clk_disable_unprepare(dcfb->clk);
+out:
+	return ret;
+}
+
+static int fsl_dcfb_remove(struct platform_device *pdev)
+{
+	struct fsl_dcfb_fb_private *dcfb = dev_get_drvdata(&pdev->dev);
+	struct fb_info *info = dcfb->fsl_dcfb_info;
+
+	fsl_dcfb_modeset(dcfb, FSL_DCFB_MOD_OFF);
+	fsl_dcfb_free_mem(info);
+
+	unregister_framebuffer(info);
+	fb_dealloc_cmap(&info->cmap);
+	framebuffer_release(dcfb->fsl_dcfb_info);
+	clk_disable_unprepare(dcfb->clk);
+
+	return 0;
+}
+
+static struct of_device_id fsl_dcfb_dt_ids[] = {
+	{ .compatible = "fsl,ls1021a-dcfb", },
+	{}
+};
+
+static struct platform_driver fsl_dcfb_driver = {
+	.driver = {
+		.name = "fsl-dcfb",
+		.owner = THIS_MODULE,
+		.of_match_table = fsl_dcfb_dt_ids,
+	},
+	.probe = fsl_dcfb_probe,
+	.remove = fsl_dcfb_remove,
+};
+
+module_platform_driver(fsl_dcfb_driver);
+
+MODULE_DESCRIPTION("Freescale Simple Display Controller FB Driver");
+MODULE_ALIAS("platform:fsl-dcfb");
+MODULE_LICENSE("GPL v2");
-- 
2.1.0.27.g96db324


^ permalink raw reply related

* [PATCH 2/4] video: fsl-dcfb: Add devicetree binding support
From: Xiubo Li @ 2014-11-24 10:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1416824454-28156-1-git-send-email-Li.Xiubo@freescale.com>

Add devicetree binding support for fsl-dcfb framebuffer driver. It
uses the generic display bindings and helper functions.

Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com>
---
 .../devicetree/bindings/video/fsl,dcfb.txt         | 52 ++++++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/fsl,dcfb.txt

diff --git a/Documentation/devicetree/bindings/video/fsl,dcfb.txt b/Documentation/devicetree/bindings/video/fsl,dcfb.txt
new file mode 100644
index 0000000..2f3d02b
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/fsl,dcfb.txt
@@ -0,0 +1,52 @@
+* Freescale Simple Display Controller FB Driver
+
+== For dcfb node =+Required properties:
+- compatible:		Should be one of "fsl,ls1021a-dcfb".
+- reg:			Address and length of the register set for dcfb.
+- clocks:		From common clock binding: handle to dcfb clock.
+- clock-names:		From common clock binding: Shall be "dcfb".
+- display:		The phandle to display node.
+
+Optional properties:
+- scfg-controller:	The phandle of scfg node.
+
+== For display sub-node =+Required properties:
+- bits-per-pixel:	<16> for RGB565,
+			<24> for RGB888,
+			<32> for RGB8888.
+
+Required timing node for dispplay sub-node:
+- display-timings:	Refer to binding doc display-timing.txt for details.
+
+Examples:
+dcfb: dcfb@2ce0000 {
+	compatible = "fsl,ls1021a-dcfb";
+	reg = <0x0 0x2ce0000 0x0 0x10000>;
+	clocks = <&platform_clk 0>;
+	clock-names = "dcfb";
+	scfg-controller = <&scfg>;
+	display = <&display>;
+
+	display: display@0 {
+		bits-per-pixel = <24>;
+
+		display-timings {
+			native-mode = <&timing0>;
+			timing0: nl4827hc19 {
+				clock-frequency = <10870000>;
+				hactive = <480>;
+				vactive = <272>;
+				hback-porch = <2>;
+				hfront-porch = <2>;
+				vback-porch = <1>;
+				vfront-porch = <1>;
+				hsync-len = <41>;
+				vsync-len = <2>;
+				hsync-active = <1>;
+				vsync-active = <1>;
+			};
+		};
+	};
+};
-- 
2.1.0.27.g96db324


^ permalink raw reply related

* [PATCH 3/4] ARM: ls1021a: dtsi: Add dt node support for dcfb.
From: Xiubo Li @ 2014-11-24 10:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1416824454-28156-1-git-send-email-Li.Xiubo@freescale.com>

On LS1021A SoC, the dcfb device is in BE mode.

Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com>
---
 arch/arm/boot/dts/ls1021a.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index c70bb27..740a04e 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -383,6 +383,16 @@
 				 <&platform_clk 1>;
 		};
 
+		dcfb: dcfb@2ce0000 {
+			compatible = "fsl,ls1021a-dcfb";
+			reg = <0x0 0x2ce0000 0x0 0x10000>;
+			clocks = <&platform_clk 0>;
+			clock-names = "dcfb";
+			scfg-controller = <&scfg>;
+			big-endian;
+			status = "disabled";
+		};
+
 		mdio0: mdio@2d24000 {
 			compatible = "gianfar";
 			device_type = "mdio";
-- 
2.1.0.27.g96db324


^ permalink raw reply related

* [PATCH 4/4] ARM: ls1021a: dts: Add and enable dt node for dcfb.
From: Xiubo Li @ 2014-11-24 10:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1416824454-28156-1-git-send-email-Li.Xiubo@freescale.com>

On LS1021A TWR board, the TFT LCD panel is WQVGA "480x272", and
the bpp is 24.

Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com>
---
 arch/arm/boot/dts/ls1021a-twr.dts | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm/boot/dts/ls1021a-twr.dts b/arch/arm/boot/dts/ls1021a-twr.dts
index a2c591e..3602286 100644
--- a/arch/arm/boot/dts/ls1021a-twr.dts
+++ b/arch/arm/boot/dts/ls1021a-twr.dts
@@ -58,6 +58,32 @@
 	};
 };
 
+&dcfb {
+	display = <&display>;
+	status = "okay";
+
+	display: display@0 {
+		bits-per-pixel = <24>;
+
+		display-timings {
+			native-mode = <&timing0>;
+			timing0: nl4827hc19 {
+				clock-frequency = <10870000>;
+				hactive = <480>;
+				vactive = <272>;
+				hback-porch = <2>;
+				hfront-porch = <2>;
+				vback-porch = <2>;
+				vfront-porch = <2>;
+				hsync-len = <41>;
+				vsync-len = <4>;
+				hsync-active = <1>;
+				vsync-active = <1>;
+			};
+		};
+	};
+};
+
 &dspi1 {
 	bus-num = <0>;
 	status = "okay";
-- 
2.1.0.27.g96db324


^ permalink raw reply related

* Re: [PATCH v2 1/5] video: omapdss: Add opa362 driver
From: Tomi Valkeinen @ 2014-11-24 11:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <BF6765C1-8D5C-4ABA-8796-195058C82E17@goldelico.com>

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

On 19/11/14 17:10, Dr. H. Nikolaus Schaller wrote:

>> You don't need to ask. The connector calls invert_vid_out_polarity
>> before enabling the output.
> 
> Unfortunately it doesn’t. At least not always.
> 
> It does only for pdata systems but not for DT based systems:
> 
> 	if (!ddata->dev->of_node) {
> 		in->ops.atv->set_type(in, ddata->connector_type);
> 		in->ops.atv->invert_vid_out_polarity(in,
> 			ddata->invert_polarity);
> 	}
> 
> Not calling is in our case different from calling with ddata->invert_polarity == 0.

Ah, sorry, my mistake. I should've read the code more carefully =).

So, with DT only approach, those calls above are not supported. If you
make the OPA driver DT only, you can remove those functions.

You only need to set the invert-polarity property in the venc DT node.

 Tomi



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

^ permalink raw reply

* Re: [PATCH v7.1 00/19] Rework OMAP4+ HDMI audio support
From: Jyri Sarha @ 2014-11-24 14:55 UTC (permalink / raw)
  To: Mark Brown
  Cc: Tomi Valkeinen, alsa-devel, linux-fbdev, linux-omap,
	peter.ujfalusi, liam.r.girdwood
In-Reply-To: <20141121163815.GT3815@sirena.org.uk>

On 11/21/2014 06:38 PM, Mark Brown wrote:
> On Fri, Nov 21, 2014 at 02:10:11PM +0200, Jyri Sarha wrote:
>
>> OMAP HDMI audio is fundamentally different to the case on Armada or on BBB.
>> In omap the whole HDMI IP is integrated to the SoC and there really is no
>> codec in the ASoC sense. The the cpu-dai transmits the audio directly to
>> hdmi wire and there is no i2s bus involved. So this case should not be mixed
>> with the patches Jean-Francois working on. The code is also orthogonal in
>> that sense that the latest omap-hdmi-audio uses the generic dymmy codec.
>
> The discussion seemed to be about what to do with unplugged connections
> which isn't what you're talking about there and does seem like an area
> where we should at least be aiming for common behaviour even if not a
> common implementation.
>

In the discussion we recognized three modes of operation,
a) try to keep audio device always operational even if audio is not 
going anywhere (cable is disconnected or video mode does not support audio)
b) remove the audio device when audio is not available
c) disable audio device if audio is not available and abort any ongoing 
stream when audio becomes unavailable
d) force pause on the stream when audio is not available

The implementation in the patches follows mode c) and in my mind it 
makes the most sense. The mode is not carved into stone by the current 
implementation and it can be changed if we decide so. I see no point in 
keeping the hdmi audio completely broken until we collectively decide on 
how all HDMI audio devices should behave.

> There's also all the stuff about parsing EDIDs for capabilities which
> would seem to be related to that but seems to have gone off into the
> weeds.
>

The idea of the patch set is to restore the old hdmi audio functionality 
in a form that is easier to use and maintain. Additional functionality 
can be added later. For instance restricting the allowed sample rates 
etc. based EDID Short Audio Descriptors.

Best regards,
Jyri

^ permalink raw reply


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