Linux Framebuffer Layer development
 help / color / mirror / Atom feed
* [PATCHv2 8/8] OMAP: DSS2: HDMI: improve hdmi output enable
From: Tomi Valkeinen @ 2011-09-12  9:12 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: archit, Tomi Valkeinen, Mythri P K
In-Reply-To: <1315818773-18660-1-git-send-email-tomi.valkeinen@ti.com>

Enabling HDMI output often causes sync lost errors, and almost always
causes timeout errors being printed from dispc_mgr_enable_digit_out().

The sync lost problem seems to go lessen greatly if we first enable the
HDMI output, and only then enable the DISPC output. However, as this is
only based on observations, the fix may not be perfect as the problem
may lie somewhere else. Nevertheless, HDMI works better with this patch.

This will also fix the dispc's dispc_mgr_enable_digit_out(), as the code
waits for two VSYNCs after enabling the output. If the HDMI output is
disabled (as it was previously), there are no VSYNCs and
dispc_mgr_enable_digit_out() will print timeout errors.

Cc: Mythri P K <mythripk@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap2/dss/hdmi.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 4752137..06a78b2 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -529,10 +529,10 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
 	dispc_set_digit_size(dssdev->panel.timings.x_res,
 			dssdev->panel.timings.y_res);
 
-	dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, 1);
-
 	hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 1);
 
+	dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, 1);
+
 	return 0;
 err:
 	hdmi_runtime_put();
-- 
1.7.4.1


^ permalink raw reply related

* [PATCHv2 00/15] OMAP: DSS2: EDID & detect support
From: Tomi Valkeinen @ 2011-09-12  9:13 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: archit, Tomi Valkeinen

Implement EDID reading and monitor detection support for HDMI and DVI outputs.

This set is based on the previously sent "OMAP: DSS2: misc improvements" set.

 Tomi

Changes in v2:
* Rebased on top of latest DSS changes
* Create a separate DVI driver with DDC support

Tomi Valkeinen (15):
  OMAP: DSS2: add read_edid() to omap_dss_driver struct
  OMAP: DSS2: add detect() to omap_dss_driver struct
  OMAP: DSS2: HDMI: make set_timing saner
  OMAP: DSS2: HDMI: implement read_edid()
  OMAP: DSS2: HDMI: remove edid parsing
  OMAP: DSS2: HDMI: split hdmi_core_ddc_edid
  OMAP: DSS2: HDMI: clean up edid reading & fix checksum
  OMAP: DSS2: HDMI: remove error prints in check_timings
  OMAP: DSS2: HDMI: implement detect()
  OMAP: DSS2: add panel-dvi driver
  OMAP: use dvi panel driver instead of generic-dpi
  OMAP: stalker: Remove LCD device from board file
  OMAP: DSS2: panel-generic-dpi: remove "generic" panel
  OMAP: Panda, Beagle, Overo: DVI: Add i2c_bus_num
  OMAPFB: find best mode from edid

 arch/arm/mach-omap2/board-3430sdp.c              |    7 +-
 arch/arm/mach-omap2/board-am3517evm.c            |    6 +-
 arch/arm/mach-omap2/board-cm-t35.c               |    6 +-
 arch/arm/mach-omap2/board-devkit8000.c           |    6 +-
 arch/arm/mach-omap2/board-igep0020.c             |    7 +-
 arch/arm/mach-omap2/board-omap3beagle.c          |    8 +-
 arch/arm/mach-omap2/board-omap3evm.c             |    7 +-
 arch/arm/mach-omap2/board-omap3stalker.c         |   40 +---
 arch/arm/mach-omap2/board-omap4panda.c           |    8 +-
 arch/arm/mach-omap2/board-overo.c                |    7 +-
 drivers/video/omap2/displays/Kconfig             |    7 +
 drivers/video/omap2/displays/Makefile            |    1 +
 drivers/video/omap2/displays/panel-dvi.c         |  363 ++++++++++++++++++++++
 drivers/video/omap2/displays/panel-generic-dpi.c |   24 --
 drivers/video/omap2/dss/dss.h                    |    2 +
 drivers/video/omap2/dss/dss_features.c           |    1 +
 drivers/video/omap2/dss/hdmi.c                   |  200 +++---------
 drivers/video/omap2/dss/hdmi_panel.c             |   66 +++-
 drivers/video/omap2/dss/ti_hdmi.h                |    9 +-
 drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c        |  193 +++++++-----
 drivers/video/omap2/omapfb/omapfb-main.c         |  109 ++++++-
 include/video/omap-panel-dvi.h                   |   37 +++
 include/video/omapdss.h                          |    3 +
 23 files changed, 758 insertions(+), 359 deletions(-)
 create mode 100644 drivers/video/omap2/displays/panel-dvi.c
 create mode 100644 include/video/omap-panel-dvi.h

-- 
1.7.4.1


^ permalink raw reply

* [PATCHv2 01/15] OMAP: DSS2: add read_edid() to omap_dss_driver struct
From: Tomi Valkeinen @ 2011-09-12  9:13 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1315818818-18733-1-git-send-email-tomi.valkeinen@ti.com>

read_edid() can be used to get the EDID information from the display.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 include/video/omapdss.h |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 8120433..cf7ecfb 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -615,6 +615,8 @@ struct omap_dss_driver {
 
 	int (*set_wss)(struct omap_dss_device *dssdev, u32 wss);
 	u32 (*get_wss)(struct omap_dss_device *dssdev);
+
+	int (*read_edid)(struct omap_dss_device *dssdev, u8 *buf, int len);
 };
 
 int omap_dss_register_driver(struct omap_dss_driver *);
-- 
1.7.4.1


^ permalink raw reply related

* [PATCHv2 02/15] OMAP: DSS2: add detect() to omap_dss_driver struct
From: Tomi Valkeinen @ 2011-09-12  9:13 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1315818818-18733-1-git-send-email-tomi.valkeinen@ti.com>

detect() can be used to probe if the display is connected.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 include/video/omapdss.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index cf7ecfb..c62b9a4 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -617,6 +617,7 @@ struct omap_dss_driver {
 	u32 (*get_wss)(struct omap_dss_device *dssdev);
 
 	int (*read_edid)(struct omap_dss_device *dssdev, u8 *buf, int len);
+	bool (*detect)(struct omap_dss_device *dssdev);
 };
 
 int omap_dss_register_driver(struct omap_dss_driver *);
-- 
1.7.4.1


^ permalink raw reply related

* [PATCHv2 03/15] OMAP: DSS2: HDMI: make set_timing saner
From: Tomi Valkeinen @ 2011-09-12  9:13 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: archit, Tomi Valkeinen, Mythri P K
In-Reply-To: <1315818818-18733-1-git-send-email-tomi.valkeinen@ti.com>

Currently the set_timings code for hdmi is quite strange. The display is
disabled in hdmi_omap4_panel.c before setting timings, and enabled in
hdmi.c after setting the timings. Furthermore, the timings were not
permanent, and disabling and enabling the display would lose them.

This patch makes the set_timings handling a bit better.

Cc: Mythri P K <mythripk@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap2/dss/hdmi.c       |   13 +++++++++++--
 drivers/video/omap2/dss/hdmi_panel.c |    7 +------
 2 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 06a78b2..f503aa4 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -571,11 +571,20 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
 	struct hdmi_cm cm;
 
 	hdmi.custom_set = 1;
+
 	cm = hdmi_get_code(&dssdev->panel.timings);
 	hdmi.code = cm.code;
 	hdmi.mode = cm.mode;
-	omapdss_hdmi_display_enable(dssdev);
-	hdmi.custom_set = 0;
+
+	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
+		int r;
+
+		hdmi_power_off(dssdev);
+
+		r = hdmi_power_on(dssdev);
+		if (r)
+			DSSERR("failed to power on device\n");
+	}
 }
 
 int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c
index e30182f..8c851e6 100644
--- a/drivers/video/omap2/dss/hdmi_panel.c
+++ b/drivers/video/omap2/dss/hdmi_panel.c
@@ -161,12 +161,7 @@ static void hdmi_set_timings(struct omap_dss_device *dssdev,
 	mutex_lock(&hdmi.hdmi_lock);
 
 	dssdev->panel.timings = *timings;
-
-	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
-		/* turn the hdmi off and on to get new timings to use */
-		omapdss_hdmi_display_disable(dssdev);
-		omapdss_hdmi_display_set_timing(dssdev);
-	}
+	omapdss_hdmi_display_set_timing(dssdev);
 
 	mutex_unlock(&hdmi.hdmi_lock);
 }
-- 
1.7.4.1


^ permalink raw reply related

* [PATCHv2 04/15] OMAP: DSS2: HDMI: implement read_edid()
From: Tomi Valkeinen @ 2011-09-12  9:13 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: archit, Tomi Valkeinen, Mythri P K
In-Reply-To: <1315818818-18733-1-git-send-email-tomi.valkeinen@ti.com>

Implement read_edid() for HDMI by implementing necessary functions to
hdmi.c and to hdmi_omap4_panel.c.

Cc: Mythri P K <mythripk@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap2/dss/dss.h             |    1 +
 drivers/video/omap2/dss/hdmi.c            |   19 ++++++++++++-
 drivers/video/omap2/dss/hdmi_panel.c      |   24 +++++++++++++++++
 drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c |   41 +++++++++++++++-------------
 4 files changed, 65 insertions(+), 20 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 48bba53..2e7799c 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -494,6 +494,7 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev);
 void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev);
 int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
 					struct omap_video_timings *timings);
+int omapdss_hdmi_read_edid(u8 *buf, int len);
 int hdmi_panel_init(void);
 void hdmi_panel_exit(void);
 
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index f503aa4..8a04ee1 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -372,7 +372,7 @@ static void hdmi_read_edid(struct omap_video_timings *dp)
 	if (!hdmi.edid_set)
 		ret = hdmi.ip_data.ops->read_edid(&hdmi.ip_data, hdmi.edid,
 						HDMI_EDID_MAX_LENGTH);
-	if (!ret) {
+	if (ret > 0) {
 		if (!memcmp(hdmi.edid, edid_header, sizeof(edid_header))) {
 			/* search for timings of default resolution */
 			get_edid_timing_data(hdmi.edid);
@@ -587,6 +587,23 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
 	}
 }
 
+int omapdss_hdmi_read_edid(u8 *buf, int len)
+{
+	int r;
+
+	mutex_lock(&hdmi.lock);
+
+	r = hdmi_runtime_get();
+	BUG_ON(r);
+
+	r = hdmi.ip_data.ops->read_edid(&hdmi.ip_data, buf, len);
+
+	hdmi_runtime_put();
+	mutex_unlock(&hdmi.lock);
+
+	return r;
+}
+
 int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
 {
 	int r = 0;
diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c
index 8c851e6..624f170 100644
--- a/drivers/video/omap2/dss/hdmi_panel.c
+++ b/drivers/video/omap2/dss/hdmi_panel.c
@@ -185,6 +185,29 @@ err:
 	return r;
 }
 
+static int hdmi_read_edid(struct omap_dss_device *dssdev, u8 *buf, int len)
+{
+	int r;
+
+	mutex_lock(&hdmi.hdmi_lock);
+
+	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
+		r = omapdss_hdmi_display_enable(dssdev);
+		if (r)
+			goto err;
+	}
+
+	r = omapdss_hdmi_read_edid(buf, len);
+
+	if (dssdev->state = OMAP_DSS_DISPLAY_DISABLED ||
+			dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED)
+		omapdss_hdmi_display_disable(dssdev);
+err:
+	mutex_unlock(&hdmi.hdmi_lock);
+
+	return r;
+}
+
 static struct omap_dss_driver hdmi_driver = {
 	.probe		= hdmi_panel_probe,
 	.remove		= hdmi_panel_remove,
@@ -195,6 +218,7 @@ static struct omap_dss_driver hdmi_driver = {
 	.get_timings	= hdmi_get_timings,
 	.set_timings	= hdmi_set_timings,
 	.check_timings	= hdmi_check_timings,
+	.read_edid	= hdmi_read_edid,
 	.driver			= {
 		.name   = "hdmi_panel",
 		.owner  = THIS_MODULE,
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
index 403c662..d4cdfc2 100644
--- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
@@ -370,29 +370,32 @@ int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data,
 {
 	int r = 0, n = 0, i = 0;
 	int max_ext_blocks = (max_length / 128) - 1;
+	int len;
 
 	r = hdmi_core_ddc_edid(ip_data, pedid, 0);
-	if (r) {
+	if (r)
 		return r;
-	} else {
-		n = pedid[0x7e];
 
-		/*
-		 * README: need to comply with max_length set by the caller.
-		 * Better implementation should be to allocate necessary
-		 * memory to store EDID according to nb_block field found
-		 * in first block
-		 */
-		if (n > max_ext_blocks)
-			n = max_ext_blocks;
+	len = 128;
+	n = pedid[0x7e];
 
-		for (i = 1; i <= n; i++) {
-			r = hdmi_core_ddc_edid(ip_data, pedid, i);
-			if (r)
-				return r;
-		}
+	/*
+	 * README: need to comply with max_length set by the caller.
+	 * Better implementation should be to allocate necessary
+	 * memory to store EDID according to nb_block field found
+	 * in first block
+	 */
+	if (n > max_ext_blocks)
+		n = max_ext_blocks;
+
+	for (i = 1; i <= n; i++) {
+		r = hdmi_core_ddc_edid(ip_data, pedid, i);
+		if (r)
+			return r;
+		len += 128;
 	}
-	return 0;
+
+	return len;
 }
 
 static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
-- 
1.7.4.1


^ permalink raw reply related

* [PATCHv2 05/15] OMAP: DSS2: HDMI: remove edid parsing
From: Tomi Valkeinen @ 2011-09-12  9:13 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: archit, Tomi Valkeinen, Mythri P K
In-Reply-To: <1315818818-18733-1-git-send-email-tomi.valkeinen@ti.com>

OMAPFB handles EDID parsing now, using the common helper functions in
fbdev. We can remove the EDID parsing from HDMI driver.

Cc: Mythri P K <mythripk@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap2/dss/hdmi.c       |  154 ----------------------------------
 drivers/video/omap2/dss/hdmi_panel.c |    8 +--
 2 files changed, 1 insertions(+), 161 deletions(-)

diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 8a04ee1..bf85cba 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -70,9 +70,6 @@ static struct {
 	struct hdmi_ip_data ip_data;
 	int code;
 	int mode;
-	u8 edid[HDMI_EDID_MAX_LENGTH];
-	u8 edid_set;
-	bool custom_set;
 
 	struct clk *sys_clk;
 } hdmi;
@@ -162,8 +159,6 @@ static const int code_vesa[85] = {
 	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
 	-1, 27, 28, -1, 33};
 
-static const u8 edid_header[8] = {0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0};
-
 static int hdmi_runtime_get(void)
 {
 	int r;
@@ -193,21 +188,6 @@ int hdmi_init_display(struct omap_dss_device *dssdev)
 	return 0;
 }
 
-static void copy_hdmi_to_dss_timings(
-		const struct hdmi_video_timings *hdmi_timings,
-		struct omap_video_timings *timings)
-{
-	timings->x_res = hdmi_timings->x_res;
-	timings->y_res = hdmi_timings->y_res;
-	timings->pixel_clock = hdmi_timings->pixel_clock;
-	timings->hbp = hdmi_timings->hbp;
-	timings->hfp = hdmi_timings->hfp;
-	timings->hsw = hdmi_timings->hsw;
-	timings->vbp = hdmi_timings->vbp;
-	timings->vfp = hdmi_timings->vfp;
-	timings->vsw = hdmi_timings->vsw;
-}
-
 static int get_timings_index(void)
 {
 	int code;
@@ -270,130 +250,6 @@ static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing)
 	return cm;
 }
 
-static void get_horz_vert_timing_info(int current_descriptor_addrs, u8 *edid ,
-		struct omap_video_timings *timings)
-{
-	/* X and Y resolution */
-	timings->x_res = (((edid[current_descriptor_addrs + 4] & 0xF0) << 4) |
-			 edid[current_descriptor_addrs + 2]);
-	timings->y_res = (((edid[current_descriptor_addrs + 7] & 0xF0) << 4) |
-			 edid[current_descriptor_addrs + 5]);
-
-	timings->pixel_clock = ((edid[current_descriptor_addrs + 1] << 8) |
-				edid[current_descriptor_addrs]);
-
-	timings->pixel_clock = 10 * timings->pixel_clock;
-
-	/* HORIZONTAL FRONT PORCH */
-	timings->hfp = edid[current_descriptor_addrs + 8] |
-			((edid[current_descriptor_addrs + 11] & 0xc0) << 2);
-	/* HORIZONTAL SYNC WIDTH */
-	timings->hsw = edid[current_descriptor_addrs + 9] |
-			((edid[current_descriptor_addrs + 11] & 0x30) << 4);
-	/* HORIZONTAL BACK PORCH */
-	timings->hbp = (((edid[current_descriptor_addrs + 4] & 0x0F) << 8) |
-			edid[current_descriptor_addrs + 3]) -
-			(timings->hfp + timings->hsw);
-	/* VERTICAL FRONT PORCH */
-	timings->vfp = ((edid[current_descriptor_addrs + 10] & 0xF0) >> 4) |
-			((edid[current_descriptor_addrs + 11] & 0x0f) << 2);
-	/* VERTICAL SYNC WIDTH */
-	timings->vsw = (edid[current_descriptor_addrs + 10] & 0x0F) |
-			((edid[current_descriptor_addrs + 11] & 0x03) << 4);
-	/* VERTICAL BACK PORCH */
-	timings->vbp = (((edid[current_descriptor_addrs + 7] & 0x0F) << 8) |
-			edid[current_descriptor_addrs + 6]) -
-			(timings->vfp + timings->vsw);
-
-}
-
-/* Description : This function gets the resolution information from EDID */
-static void get_edid_timing_data(u8 *edid)
-{
-	u8 count;
-	u16 current_descriptor_addrs;
-	struct hdmi_cm cm;
-	struct omap_video_timings edid_timings;
-
-	/* search block 0, there are 4 DTDs arranged in priority order */
-	for (count = 0; count < EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR; count++) {
-		current_descriptor_addrs -			EDID_DESCRIPTOR_BLOCK0_ADDRESS +
-			count * EDID_TIMING_DESCRIPTOR_SIZE;
-		get_horz_vert_timing_info(current_descriptor_addrs,
-				edid, &edid_timings);
-		cm = hdmi_get_code(&edid_timings);
-		DSSDBG("Block0[%d] value matches code = %d , mode = %d\n",
-			count, cm.code, cm.mode);
-		if (cm.code = -1) {
-			continue;
-		} else {
-			hdmi.code = cm.code;
-			hdmi.mode = cm.mode;
-			DSSDBG("code = %d , mode = %d\n",
-				hdmi.code, hdmi.mode);
-			return;
-		}
-	}
-	if (edid[0x7e] != 0x00) {
-		for (count = 0; count < EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR;
-			count++) {
-			current_descriptor_addrs -			EDID_DESCRIPTOR_BLOCK1_ADDRESS +
-			count * EDID_TIMING_DESCRIPTOR_SIZE;
-			get_horz_vert_timing_info(current_descriptor_addrs,
-						edid, &edid_timings);
-			cm = hdmi_get_code(&edid_timings);
-			DSSDBG("Block1[%d] value matches code = %d, mode = %d",
-				count, cm.code, cm.mode);
-			if (cm.code = -1) {
-				continue;
-			} else {
-				hdmi.code = cm.code;
-				hdmi.mode = cm.mode;
-				DSSDBG("code = %d , mode = %d\n",
-					hdmi.code, hdmi.mode);
-				return;
-			}
-		}
-	}
-
-	DSSINFO("no valid timing found , falling back to VGA\n");
-	hdmi.code = 4; /* setting default value of 640 480 VGA */
-	hdmi.mode = HDMI_DVI;
-}
-
-static void hdmi_read_edid(struct omap_video_timings *dp)
-{
-	int ret = 0, code;
-
-	memset(hdmi.edid, 0, HDMI_EDID_MAX_LENGTH);
-
-	if (!hdmi.edid_set)
-		ret = hdmi.ip_data.ops->read_edid(&hdmi.ip_data, hdmi.edid,
-						HDMI_EDID_MAX_LENGTH);
-	if (ret > 0) {
-		if (!memcmp(hdmi.edid, edid_header, sizeof(edid_header))) {
-			/* search for timings of default resolution */
-			get_edid_timing_data(hdmi.edid);
-			hdmi.edid_set = true;
-		}
-	} else {
-		DSSWARN("failed to read E-EDID\n");
-	}
-
-	if (!hdmi.edid_set) {
-		DSSINFO("fallback to VGA\n");
-		hdmi.code = 4; /* setting default value of 640 480 VGA */
-		hdmi.mode = HDMI_DVI;
-	}
-
-	code = get_timings_index();
-
-	copy_hdmi_to_dss_timings(&cea_vesa_timings[code].timings, dp);
-
-}
-
 static void update_hdmi_timings(struct hdmi_config *cfg,
 		struct omap_video_timings *timings, int code)
 {
@@ -479,13 +335,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
 		dssdev->panel.timings.x_res,
 		dssdev->panel.timings.y_res);
 
-	if (!hdmi.custom_set) {
-		DSSDBG("Read EDID as no EDID is not set on poweron\n");
-		hdmi_read_edid(p);
-	}
 	code = get_timings_index();
-	copy_hdmi_to_dss_timings(&cea_vesa_timings[code].timings,
-			&dssdev->panel.timings);
 	update_hdmi_timings(&hdmi.ip_data.cfg, p, code);
 
 	phy = p->pixel_clock;
@@ -547,8 +397,6 @@ static void hdmi_power_off(struct omap_dss_device *dssdev)
 	hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
 	hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
 	hdmi_runtime_put();
-
-	hdmi.edid_set = 0;
 }
 
 int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
@@ -570,8 +418,6 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
 {
 	struct hdmi_cm cm;
 
-	hdmi.custom_set = 1;
-
 	cm = hdmi_get_code(&dssdev->panel.timings);
 	hdmi.code = cm.code;
 	hdmi.mode = cm.mode;
diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c
index 624f170..79a3a5a 100644
--- a/drivers/video/omap2/dss/hdmi_panel.c
+++ b/drivers/video/omap2/dss/hdmi_panel.c
@@ -40,13 +40,7 @@ static int hdmi_panel_probe(struct omap_dss_device *dssdev)
 	dssdev->panel.config = OMAP_DSS_LCD_TFT |
 			OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS;
 
-	/*
-	 * Initialize the timings to 640 * 480
-	 * This is only for framebuffer update not for TV timing setting
-	 * Setting TV timing will be done only on enable
-	 */
-	dssdev->panel.timings.x_res = 640;
-	dssdev->panel.timings.y_res = 480;
+	dssdev->panel.timings = (struct omap_video_timings){640, 480, 25175, 96, 16, 48, 2 , 11, 31};
 
 	DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n",
 		dssdev->panel.timings.x_res,
-- 
1.7.4.1


^ permalink raw reply related

* [PATCHv2 06/15] OMAP: DSS2: HDMI: split hdmi_core_ddc_edid
From: Tomi Valkeinen @ 2011-09-12  9:13 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: archit, Tomi Valkeinen, Mythri P K
In-Reply-To: <1315818818-18733-1-git-send-email-tomi.valkeinen@ti.com>

Split the DDC initialization off from hdmi_core_ddc_edid() into a
separate function hdmi_core_ddc_init(). This cleans up the
implementation.

Cc: Mythri P K <mythripk@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c |  117 ++++++++++++++++------------
 1 files changed, 67 insertions(+), 50 deletions(-)

diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
index d4cdfc2..ecf854e 100644
--- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
@@ -264,92 +264,105 @@ void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data)
 	hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
 }
 
-static int hdmi_core_ddc_edid(struct hdmi_ip_data *ip_data,
-						u8 *pedid, int ext)
+static int hdmi_core_ddc_init(struct hdmi_ip_data *ip_data)
 {
-	u32 i, j;
-	char checksum = 0;
-	u32 offset = 0;
-	void __iomem *core_sys_base = hdmi_core_sys_base(ip_data);
+	void __iomem *base = hdmi_core_sys_base(ip_data);
 
 	/* Turn on CLK for DDC */
-	REG_FLD_MOD(hdmi_av_base(ip_data), HDMI_CORE_AV_DPD, 0x7, 2, 0);
+	REG_FLD_MOD(base, HDMI_CORE_AV_DPD, 0x7, 2, 0);
+
+	/* IN_PROG */
+	if (REG_GET(base, HDMI_CORE_DDC_STATUS, 4, 4) = 1) {
+		/* Abort transaction */
+		REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0xf, 3, 0);
+		/* IN_PROG */
+		if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS,
+					4, 4, 0) != 0) {
+			DSSERR("Timeout aborting DDC transaction\n");
+			return -ETIMEDOUT;
+		}
+	}
 
-	/*
-	 * SW HACK : Without the Delay DDC(i2c bus) reads 0 values /
-	 * right shifted values( The behavior is not consistent and seen only
-	 * with some TV's)
-	 */
-	usleep_range(800, 1000);
+	/* Clk SCL Devices */
+	REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0xA, 3, 0);
+
+	/* HDMI_CORE_DDC_STATUS_IN_PROG */
+	if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS,
+				4, 4, 0) != 0) {
+		DSSERR("Timeout starting SCL clock\n");
+		return -ETIMEDOUT;
+	}
 
-	if (!ext) {
-		/* Clk SCL Devices */
-		REG_FLD_MOD(core_sys_base, HDMI_CORE_DDC_CMD, 0xA, 3, 0);
+	/* Clear FIFO */
+	REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x9, 3, 0);
 
-		/* HDMI_CORE_DDC_STATUS_IN_PROG */
-		if (hdmi_wait_for_bit_change(core_sys_base,
-					HDMI_CORE_DDC_STATUS, 4, 4, 0) != 0) {
-			pr_err("Failed to program DDC\n");
-			return -ETIMEDOUT;
-		}
+	/* HDMI_CORE_DDC_STATUS_IN_PROG */
+	if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS,
+				4, 4, 0) != 0) {
+		DSSERR("Timeout clearing DDC fifo\n");
+		return -ETIMEDOUT;
+	}
 
-		/* Clear FIFO */
-		REG_FLD_MOD(core_sys_base, HDMI_CORE_DDC_CMD, 0x9, 3, 0);
+	return 0;
+}
 
-		/* HDMI_CORE_DDC_STATUS_IN_PROG */
-		if (hdmi_wait_for_bit_change(core_sys_base,
-					HDMI_CORE_DDC_STATUS, 4, 4, 0) != 0) {
-			pr_err("Failed to program DDC\n");
-			return -ETIMEDOUT;
-		}
+static int hdmi_core_ddc_edid(struct hdmi_ip_data *ip_data,
+		u8 *pedid, int ext)
+{
+	void __iomem *base = hdmi_core_sys_base(ip_data);
+	u32 i, j;
+	char checksum = 0;
+	u32 offset = 0;
 
-	} else {
-		if (ext % 2 != 0)
-			offset = 0x80;
+	/* HDMI_CORE_DDC_STATUS_IN_PROG */
+	if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS,
+				4, 4, 0) != 0) {
+		DSSERR("Timeout waiting DDC to be ready\n");
+		return -ETIMEDOUT;
 	}
 
+	if (ext % 2 != 0)
+		offset = 0x80;
+
 	/* Load Segment Address Register */
-	REG_FLD_MOD(core_sys_base, HDMI_CORE_DDC_SEGM, ext/2, 7, 0);
+	REG_FLD_MOD(base, HDMI_CORE_DDC_SEGM, ext / 2, 7, 0);
 
 	/* Load Slave Address Register */
-	REG_FLD_MOD(core_sys_base, HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1);
+	REG_FLD_MOD(base, HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1);
 
 	/* Load Offset Address Register */
-	REG_FLD_MOD(core_sys_base, HDMI_CORE_DDC_OFFSET, offset, 7, 0);
+	REG_FLD_MOD(base, HDMI_CORE_DDC_OFFSET, offset, 7, 0);
 
 	/* Load Byte Count */
-	REG_FLD_MOD(core_sys_base, HDMI_CORE_DDC_COUNT1, 0x80, 7, 0);
-	REG_FLD_MOD(core_sys_base, HDMI_CORE_DDC_COUNT2, 0x0, 1, 0);
+	REG_FLD_MOD(base, HDMI_CORE_DDC_COUNT1, 0x80, 7, 0);
+	REG_FLD_MOD(base, HDMI_CORE_DDC_COUNT2, 0x0, 1, 0);
 
 	/* Set DDC_CMD */
 	if (ext)
-		REG_FLD_MOD(core_sys_base, HDMI_CORE_DDC_CMD, 0x4, 3, 0);
+		REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x4, 3, 0);
 	else
-		REG_FLD_MOD(core_sys_base, HDMI_CORE_DDC_CMD, 0x2, 3, 0);
+		REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x2, 3, 0);
 
 	/* HDMI_CORE_DDC_STATUS_BUS_LOW */
-	if (REG_GET(core_sys_base,
-					HDMI_CORE_DDC_STATUS, 6, 6) = 1) {
+	if (REG_GET(base, HDMI_CORE_DDC_STATUS, 6, 6) = 1) {
 		pr_err("I2C Bus Low?\n");
 		return -EIO;
 	}
 	/* HDMI_CORE_DDC_STATUS_NO_ACK */
-	if (REG_GET(core_sys_base,
-					HDMI_CORE_DDC_STATUS, 5, 5) = 1) {
+	if (REG_GET(base, HDMI_CORE_DDC_STATUS, 5, 5) = 1) {
 		pr_err("I2C No Ack\n");
 		return -EIO;
 	}
 
 	i = ext * 128;
 	j = 0;
-	while (((REG_GET(core_sys_base, HDMI_CORE_DDC_STATUS, 4, 4) = 1) ||
-			(REG_GET(core_sys_base,
-			HDMI_CORE_DDC_STATUS, 2, 2) = 0)) && j < 128) {
+	while (((REG_GET(base, HDMI_CORE_DDC_STATUS, 4, 4) = 1) ||
+		(REG_GET(base, HDMI_CORE_DDC_STATUS, 2, 2) = 0)) &&
+			j < 128) {
 
-		if (REG_GET(core_sys_base, HDMI_CORE_DDC_STATUS, 2, 2) = 0) {
+		if (REG_GET(base, HDMI_CORE_DDC_STATUS, 2, 2) = 0) {
 			/* FIFO not empty */
-			pedid[i++] = REG_GET(core_sys_base,
-						HDMI_CORE_DDC_DATA, 7, 0);
+			pedid[i++] = REG_GET(base, HDMI_CORE_DDC_DATA, 7, 0);
 			j++;
 		}
 	}
@@ -372,6 +385,10 @@ int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data,
 	int max_ext_blocks = (max_length / 128) - 1;
 	int len;
 
+	r = hdmi_core_ddc_init(ip_data);
+	if (r)
+		return r;
+
 	r = hdmi_core_ddc_edid(ip_data, pedid, 0);
 	if (r)
 		return r;
-- 
1.7.4.1


^ permalink raw reply related

* [PATCHv2 07/15] OMAP: DSS2: HDMI: clean up edid reading & fix checksum
From: Tomi Valkeinen @ 2011-09-12  9:13 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: archit, Tomi Valkeinen, Mythri P K
In-Reply-To: <1315818818-18733-1-git-send-email-tomi.valkeinen@ti.com>

Clean up reading of EDID by passing direct address to the block being
read, instead of start address of the whole EDID memory area. Rewrite
the loop which reads the EDID.

This also fixes the checksum calculation, which used to calculate the
checksum only for the first block.

Cc: Mythri P K <mythripk@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap2/dss/ti_hdmi.h         |    6 +--
 drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c |   67 +++++++++++++++--------------
 2 files changed, 36 insertions(+), 37 deletions(-)

diff --git a/drivers/video/omap2/dss/ti_hdmi.h b/drivers/video/omap2/dss/ti_hdmi.h
index acf1022..390cd85b 100644
--- a/drivers/video/omap2/dss/ti_hdmi.h
+++ b/drivers/video/omap2/dss/ti_hdmi.h
@@ -92,8 +92,7 @@ struct ti_hdmi_ip_ops {
 
 	void (*phy_disable)(struct hdmi_ip_data *ip_data);
 
-	int (*read_edid)(struct hdmi_ip_data *ip_data,
-			u8 *pedid, u16 max_length);
+	int (*read_edid)(struct hdmi_ip_data *ip_data, u8 *edid, int len);
 
 	int (*pll_enable)(struct hdmi_ip_data *ip_data);
 
@@ -114,8 +113,7 @@ struct hdmi_ip_data {
 };
 int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data);
 void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data);
-int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data,
-					u8 *pedid, u16 max_length);
+int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, u8 *edid, int len);
 void ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start);
 int ti_hdmi_4xxx_pll_enable(struct hdmi_ip_data *ip_data);
 void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data);
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
index ecf854e..e9885dc 100644
--- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
@@ -310,8 +310,8 @@ static int hdmi_core_ddc_edid(struct hdmi_ip_data *ip_data,
 		u8 *pedid, int ext)
 {
 	void __iomem *base = hdmi_core_sys_base(ip_data);
-	u32 i, j;
-	char checksum = 0;
+	u32 i;
+	char checksum;
 	u32 offset = 0;
 
 	/* HDMI_CORE_DDC_STATUS_IN_PROG */
@@ -354,21 +354,31 @@ static int hdmi_core_ddc_edid(struct hdmi_ip_data *ip_data,
 		return -EIO;
 	}
 
-	i = ext * 128;
-	j = 0;
-	while (((REG_GET(base, HDMI_CORE_DDC_STATUS, 4, 4) = 1) ||
-		(REG_GET(base, HDMI_CORE_DDC_STATUS, 2, 2) = 0)) &&
-			j < 128) {
+	for (i = 0; i < 0x80; ++i) {
+		int t;
 
-		if (REG_GET(base, HDMI_CORE_DDC_STATUS, 2, 2) = 0) {
-			/* FIFO not empty */
-			pedid[i++] = REG_GET(base, HDMI_CORE_DDC_DATA, 7, 0);
-			j++;
+		/* IN_PROG */
+		if (REG_GET(base, HDMI_CORE_DDC_STATUS, 4, 4) = 0) {
+			DSSERR("operation stopped when reading edid\n");
+			return -EIO;
+		}
+
+		t = 0;
+		/* FIFO_EMPTY */
+		while (REG_GET(base, HDMI_CORE_DDC_STATUS, 2, 2) = 1) {
+			if (t++ > 10000) {
+				DSSERR("timeout reading edid\n");
+				return -ETIMEDOUT;
+			}
+			udelay(1);
 		}
+
+		pedid[i] = REG_GET(base, HDMI_CORE_DDC_DATA, 7, 0);
 	}
 
-	for (j = 0; j < 128; j++)
-		checksum += pedid[j];
+	checksum = 0;
+	for (i = 0; i < 0x80; ++i)
+		checksum += pedid[i];
 
 	if (checksum != 0) {
 		pr_err("E-EDID checksum failed!!\n");
@@ -379,40 +389,31 @@ static int hdmi_core_ddc_edid(struct hdmi_ip_data *ip_data,
 }
 
 int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data,
-				u8 *pedid, u16 max_length)
+				u8 *edid, int len)
 {
-	int r = 0, n = 0, i = 0;
-	int max_ext_blocks = (max_length / 128) - 1;
-	int len;
+	int r, l;
+
+	if (len < 128)
+		return -EINVAL;
 
 	r = hdmi_core_ddc_init(ip_data);
 	if (r)
 		return r;
 
-	r = hdmi_core_ddc_edid(ip_data, pedid, 0);
+	r = hdmi_core_ddc_edid(ip_data, edid, 0);
 	if (r)
 		return r;
 
-	len = 128;
-	n = pedid[0x7e];
-
-	/*
-	 * README: need to comply with max_length set by the caller.
-	 * Better implementation should be to allocate necessary
-	 * memory to store EDID according to nb_block field found
-	 * in first block
-	 */
-	if (n > max_ext_blocks)
-		n = max_ext_blocks;
+	l = 128;
 
-	for (i = 1; i <= n; i++) {
-		r = hdmi_core_ddc_edid(ip_data, pedid, i);
+	if (len >= 128 * 2 && edid[0x7e] > 0) {
+		r = hdmi_core_ddc_edid(ip_data, edid + 0x80, 1);
 		if (r)
 			return r;
-		len += 128;
+		l += 128;
 	}
 
-	return len;
+	return l;
 }
 
 static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
-- 
1.7.4.1


^ permalink raw reply related

* [PATCHv2 08/15] OMAP: DSS2: HDMI: remove error prints in check_timings
From: Tomi Valkeinen @ 2011-09-12  9:13 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: archit, Tomi Valkeinen, Mythri P K
In-Reply-To: <1315818818-18733-1-git-send-email-tomi.valkeinen@ti.com>

check_timings() is supposed to be used to verify if timings are ok or
not. Currently the HDMI driver prints error messages if the timings are
not ok. This is not right, as it is no error to give invalid timings to
check_timings().

Remove the error prints.

Cc: Mythri P K <mythripk@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap2/dss/hdmi.c       |    1 -
 drivers/video/omap2/dss/hdmi_panel.c |    6 +-----
 2 files changed, 1 insertions(+), 6 deletions(-)

diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index bf85cba..fb85ce5 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -406,7 +406,6 @@ int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
 
 	cm = hdmi_get_code(timings);
 	if (cm.code = -1) {
-		DSSERR("Invalid timing entered\n");
 		return -EINVAL;
 	}
 
diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c
index 79a3a5a..71aa813 100644
--- a/drivers/video/omap2/dss/hdmi_panel.c
+++ b/drivers/video/omap2/dss/hdmi_panel.c
@@ -170,11 +170,7 @@ static int hdmi_check_timings(struct omap_dss_device *dssdev,
 	mutex_lock(&hdmi.hdmi_lock);
 
 	r = omapdss_hdmi_display_check_timing(dssdev, timings);
-	if (r) {
-		DSSERR("Timing cannot be applied\n");
-		goto err;
-	}
-err:
+
 	mutex_unlock(&hdmi.hdmi_lock);
 	return r;
 }
-- 
1.7.4.1


^ permalink raw reply related

* [PATCHv2 09/15] OMAP: DSS2: HDMI: implement detect()
From: Tomi Valkeinen @ 2011-09-12  9:13 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: archit, Tomi Valkeinen, Mythri P K
In-Reply-To: <1315818818-18733-1-git-send-email-tomi.valkeinen@ti.com>

Implement detect() by checking the hot plug detect status.

The implementation is not very good, as it always turns on the HDMI
output to get the detection working. HDMI driver needs improvements so
that we could enable only core parts of it.

Cc: Mythri P K <mythripk@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap2/dss/dss.h             |    1 +
 drivers/video/omap2/dss/dss_features.c    |    1 +
 drivers/video/omap2/dss/hdmi.c            |   17 +++++++++++++++++
 drivers/video/omap2/dss/hdmi_panel.c      |   25 +++++++++++++++++++++++++
 drivers/video/omap2/dss/ti_hdmi.h         |    3 +++
 drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c |   12 ++++++++++++
 6 files changed, 59 insertions(+), 0 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 2e7799c..f58c302 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -495,6 +495,7 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev);
 int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
 					struct omap_video_timings *timings);
 int omapdss_hdmi_read_edid(u8 *buf, int len);
+bool omapdss_hdmi_detect(void);
 int hdmi_panel_init(void);
 void hdmi_panel_exit(void);
 
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 076f399..ab41665 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -440,6 +440,7 @@ static const struct ti_hdmi_ip_ops omap4_hdmi_functions = {
 	.phy_enable		=	ti_hdmi_4xxx_phy_enable,
 	.phy_disable		=	ti_hdmi_4xxx_phy_disable,
 	.read_edid		=	ti_hdmi_4xxx_read_edid,
+	.detect			=	ti_hdmi_4xxx_detect,
 	.pll_enable		=	ti_hdmi_4xxx_pll_enable,
 	.pll_disable		=	ti_hdmi_4xxx_pll_disable,
 	.video_enable		=	ti_hdmi_4xxx_wp_video_start,
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index fb85ce5..7818670 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -449,6 +449,23 @@ int omapdss_hdmi_read_edid(u8 *buf, int len)
 	return r;
 }
 
+bool omapdss_hdmi_detect(void)
+{
+	int r;
+
+	mutex_lock(&hdmi.lock);
+
+	r = hdmi_runtime_get();
+	BUG_ON(r);
+
+	r = hdmi.ip_data.ops->detect(&hdmi.ip_data);
+
+	hdmi_runtime_put();
+	mutex_unlock(&hdmi.lock);
+
+	return r = 1;
+}
+
 int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
 {
 	int r = 0;
diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c
index 71aa813..533d5dc 100644
--- a/drivers/video/omap2/dss/hdmi_panel.c
+++ b/drivers/video/omap2/dss/hdmi_panel.c
@@ -25,6 +25,7 @@
 #include <linux/mutex.h>
 #include <linux/module.h>
 #include <video/omapdss.h>
+#include <linux/slab.h>
 
 #include "dss.h"
 
@@ -198,6 +199,29 @@ err:
 	return r;
 }
 
+static bool hdmi_detect(struct omap_dss_device *dssdev)
+{
+	int r;
+
+	mutex_lock(&hdmi.hdmi_lock);
+
+	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
+		r = omapdss_hdmi_display_enable(dssdev);
+		if (r)
+			goto err;
+	}
+
+	r = omapdss_hdmi_detect();
+
+	if (dssdev->state = OMAP_DSS_DISPLAY_DISABLED ||
+			dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED)
+		omapdss_hdmi_display_disable(dssdev);
+err:
+	mutex_unlock(&hdmi.hdmi_lock);
+
+	return r;
+}
+
 static struct omap_dss_driver hdmi_driver = {
 	.probe		= hdmi_panel_probe,
 	.remove		= hdmi_panel_remove,
@@ -209,6 +233,7 @@ static struct omap_dss_driver hdmi_driver = {
 	.set_timings	= hdmi_set_timings,
 	.check_timings	= hdmi_check_timings,
 	.read_edid	= hdmi_read_edid,
+	.detect		= hdmi_detect,
 	.driver			= {
 		.name   = "hdmi_panel",
 		.owner  = THIS_MODULE,
diff --git a/drivers/video/omap2/dss/ti_hdmi.h b/drivers/video/omap2/dss/ti_hdmi.h
index 390cd85b..d48603c 100644
--- a/drivers/video/omap2/dss/ti_hdmi.h
+++ b/drivers/video/omap2/dss/ti_hdmi.h
@@ -94,6 +94,8 @@ struct ti_hdmi_ip_ops {
 
 	int (*read_edid)(struct hdmi_ip_data *ip_data, u8 *edid, int len);
 
+	bool (*detect)(struct hdmi_ip_data *ip_data);
+
 	int (*pll_enable)(struct hdmi_ip_data *ip_data);
 
 	void (*pll_disable)(struct hdmi_ip_data *ip_data);
@@ -114,6 +116,7 @@ struct hdmi_ip_data {
 int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data);
 void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data);
 int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, u8 *edid, int len);
+bool ti_hdmi_4xxx_detect(struct hdmi_ip_data *ip_data);
 void ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start);
 int ti_hdmi_4xxx_pll_enable(struct hdmi_ip_data *ip_data);
 void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data);
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
index e9885dc..da7fe50 100644
--- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
@@ -416,6 +416,18 @@ int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data,
 	return l;
 }
 
+bool ti_hdmi_4xxx_detect(struct hdmi_ip_data *ip_data)
+{
+	int r;
+
+	void __iomem *base = hdmi_core_sys_base(ip_data);
+
+	/* HPD */
+	r = REG_GET(base, HDMI_CORE_SYS_SYS_STAT, 1, 1);
+
+	return r = 1;
+}
+
 static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
 			struct hdmi_core_infoframe_avi *avi_cfg,
 			struct hdmi_core_packet_enable_repeat *repeat_cfg)
-- 
1.7.4.1


^ permalink raw reply related

* [PATCHv2 10/15] OMAP: DSS2: add panel-dvi driver
From: Tomi Valkeinen @ 2011-09-12  9:13 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1315818818-18733-1-git-send-email-tomi.valkeinen@ti.com>

We have currently panel-generic-dpi driver, which is a combined driver
for dummy panels and also for DVI output.

The aim is to split the panel-generic-dpi into two, one for fixed size
dummy panels connected via DPI, and the other (this) for variable
resolution output which supports DDC channel (in practice a DVI framer
chip connected to DPI output).

Original i2c code by: Ricardo Salveti de Araujo
<ricardo.salveti@canonical.com>

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap2/displays/Kconfig     |    7 +
 drivers/video/omap2/displays/Makefile    |    1 +
 drivers/video/omap2/displays/panel-dvi.c |  363 ++++++++++++++++++++++++++++++
 include/video/omap-panel-dvi.h           |   37 +++
 4 files changed, 408 insertions(+), 0 deletions(-)
 create mode 100644 drivers/video/omap2/displays/panel-dvi.c
 create mode 100644 include/video/omap-panel-dvi.h

diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig
index 6ddb401..16e3eab 100644
--- a/drivers/video/omap2/displays/Kconfig
+++ b/drivers/video/omap2/displays/Kconfig
@@ -10,6 +10,13 @@ config PANEL_GENERIC_DPI
 	  Supports LCD Panel used in TI SDP3430 and EVM boards,
 	  OMAP3517 EVM boards and CM-T35.
 
+config PANEL_DVI
+	tristate "DVI output"
+	depends on OMAP2_DSS_DPI
+	help
+	  Driver for external monitors, connected via DVI. The driver uses i2c
+	  to read EDID information from the monitor.
+
 config PANEL_LGPHILIPS_LB035Q02
 	tristate "LG.Philips LB035Q02 LCD Panel"
 	depends on OMAP2_DSS_DPI && SPI
diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile
index d90f73c..abfda35 100644
--- a/drivers/video/omap2/displays/Makefile
+++ b/drivers/video/omap2/displays/Makefile
@@ -1,4 +1,5 @@
 obj-$(CONFIG_PANEL_GENERIC_DPI) += panel-generic-dpi.o
+obj-$(CONFIG_PANEL_DVI) += panel-dvi.o
 obj-$(CONFIG_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o
 obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
 obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o
diff --git a/drivers/video/omap2/displays/panel-dvi.c b/drivers/video/omap2/displays/panel-dvi.c
new file mode 100644
index 0000000..03eb14a
--- /dev/null
+++ b/drivers/video/omap2/displays/panel-dvi.c
@@ -0,0 +1,363 @@
+/*
+ * DVI output support
+ *
+ * Copyright (C) 2011 Texas Instruments Inc
+ * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <video/omapdss.h>
+#include <linux/i2c.h>
+#include <drm/drm_edid.h>
+
+#include <video/omap-panel-dvi.h>
+
+static const struct omap_video_timings panel_dvi_default_timings = {
+	.x_res		= 640,
+	.y_res		= 480,
+
+	.pixel_clock	= 23500,
+
+	.hfp		= 48,
+	.hsw		= 32,
+	.hbp		= 80,
+
+	.vfp		= 3,
+	.vsw		= 4,
+	.vbp		= 7,
+};
+
+struct panel_drv_data {
+	struct omap_dss_device *dssdev;
+
+	struct mutex lock;
+};
+
+static inline struct panel_dvi_platform_data
+*get_pdata(const struct omap_dss_device *dssdev)
+{
+	return dssdev->data;
+}
+
+static int panel_dvi_power_on(struct omap_dss_device *dssdev)
+{
+	struct panel_dvi_platform_data *pdata = get_pdata(dssdev);
+	int r;
+
+	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
+		return 0;
+
+	r = omapdss_dpi_display_enable(dssdev);
+	if (r)
+		goto err0;
+
+	if (pdata->platform_enable) {
+		r = pdata->platform_enable(dssdev);
+		if (r)
+			goto err1;
+	}
+
+	return 0;
+err1:
+	omapdss_dpi_display_disable(dssdev);
+err0:
+	return r;
+}
+
+static void panel_dvi_power_off(struct omap_dss_device *dssdev)
+{
+	struct panel_dvi_platform_data *pdata = get_pdata(dssdev);
+
+	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+		return;
+
+	if (pdata->platform_disable)
+		pdata->platform_disable(dssdev);
+
+	omapdss_dpi_display_disable(dssdev);
+}
+
+static int panel_dvi_probe(struct omap_dss_device *dssdev)
+{
+	struct panel_drv_data *ddata;
+
+	ddata = kzalloc(sizeof(*ddata), GFP_KERNEL);
+	if (!ddata)
+		return -ENOMEM;
+
+	dssdev->panel.timings = panel_dvi_default_timings;
+	dssdev->panel.config = OMAP_DSS_LCD_TFT;
+
+	ddata->dssdev = dssdev;
+	mutex_init(&ddata->lock);
+
+	dev_set_drvdata(&dssdev->dev, ddata);
+
+	return 0;
+}
+
+static void __exit panel_dvi_remove(struct omap_dss_device *dssdev)
+{
+	struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
+
+	mutex_lock(&ddata->lock);
+
+	dev_set_drvdata(&dssdev->dev, NULL);
+
+	mutex_unlock(&ddata->lock);
+
+	kfree(ddata);
+}
+
+static int panel_dvi_enable(struct omap_dss_device *dssdev)
+{
+	struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
+	int r;
+
+	mutex_lock(&ddata->lock);
+
+	r = panel_dvi_power_on(dssdev);
+	if (r = 0)
+		dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+	mutex_unlock(&ddata->lock);
+
+	return r;
+}
+
+static void panel_dvi_disable(struct omap_dss_device *dssdev)
+{
+	struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
+
+	mutex_lock(&ddata->lock);
+
+	panel_dvi_power_off(dssdev);
+
+	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+
+	mutex_unlock(&ddata->lock);
+}
+
+static int panel_dvi_suspend(struct omap_dss_device *dssdev)
+{
+	struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
+
+	mutex_lock(&ddata->lock);
+
+	panel_dvi_power_off(dssdev);
+
+	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
+
+	mutex_unlock(&ddata->lock);
+
+	return 0;
+}
+
+static int panel_dvi_resume(struct omap_dss_device *dssdev)
+{
+	struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
+	int r;
+
+	mutex_lock(&ddata->lock);
+
+	r = panel_dvi_power_on(dssdev);
+	if (r = 0)
+		dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+	mutex_unlock(&ddata->lock);
+
+	return r;
+}
+
+static void panel_dvi_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
+
+	mutex_lock(&ddata->lock);
+	dpi_set_timings(dssdev, timings);
+	mutex_unlock(&ddata->lock);
+}
+
+static void panel_dvi_get_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
+
+	mutex_lock(&ddata->lock);
+	*timings = dssdev->panel.timings;
+	mutex_unlock(&ddata->lock);
+}
+
+static int panel_dvi_check_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
+	int r;
+
+	mutex_lock(&ddata->lock);
+	r = dpi_check_timings(dssdev, timings);
+	mutex_unlock(&ddata->lock);
+
+	return r;
+}
+
+
+static int panel_dvi_ddc_read(struct i2c_adapter *adapter,
+		unsigned char *buf, u16 count, u8 offset)
+{
+	int r, retries;
+
+	for (retries = 3; retries > 0; retries--) {
+		struct i2c_msg msgs[] = {
+			{
+				.addr   = DDC_ADDR,
+				.flags  = 0,
+				.len    = 1,
+				.buf    = &offset,
+			}, {
+				.addr   = DDC_ADDR,
+				.flags  = I2C_M_RD,
+				.len    = count,
+				.buf    = buf,
+			}
+		};
+
+		r = i2c_transfer(adapter, msgs, 2);
+		if (r = 2)
+			return 0;
+
+		if (r != -EAGAIN)
+			break;
+	}
+
+	return r < 0 ? r : -EIO;
+}
+
+static int panel_dvi_read_edid(struct omap_dss_device *dssdev,
+		u8 *edid, int len)
+{
+	struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
+	struct panel_dvi_platform_data *pdata = get_pdata(dssdev);
+	struct i2c_adapter *adapter;
+	int r, l, bytes_read;
+
+	mutex_lock(&ddata->lock);
+
+	if (pdata->i2c_bus_num = 0) {
+		r = -ENODEV;
+		goto err;
+	}
+
+	adapter = i2c_get_adapter(pdata->i2c_bus_num);
+	if (!adapter) {
+		dev_err(&dssdev->dev, "Failed to get I2C adapter, bus %d\n",
+				pdata->i2c_bus_num);
+		r = -EINVAL;
+		goto err;
+	}
+
+	l = min(EDID_LENGTH, len);
+	r = panel_dvi_ddc_read(adapter, edid, l, 0);
+	if (r)
+		goto err;
+
+	bytes_read = l;
+
+	/* if there are extensions, read second block */
+	if (len > EDID_LENGTH && edid[0x7e] > 0) {
+		l = min(EDID_LENGTH, len - EDID_LENGTH);
+
+		r = panel_dvi_ddc_read(adapter, edid + EDID_LENGTH,
+				l, EDID_LENGTH);
+		if (r)
+			goto err;
+
+		bytes_read += l;
+	}
+
+	mutex_unlock(&ddata->lock);
+
+	return bytes_read;
+
+err:
+	mutex_unlock(&ddata->lock);
+	return r;
+}
+
+static bool panel_dvi_detect(struct omap_dss_device *dssdev)
+{
+	struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
+	struct panel_dvi_platform_data *pdata = get_pdata(dssdev);
+	struct i2c_adapter *adapter;
+	unsigned char out;
+	int r;
+
+	mutex_lock(&ddata->lock);
+
+	if (pdata->i2c_bus_num = 0)
+		goto out;
+
+	adapter = i2c_get_adapter(pdata->i2c_bus_num);
+	if (!adapter)
+		goto out;
+
+	r = panel_dvi_ddc_read(adapter, &out, 1, 0);
+
+	mutex_unlock(&ddata->lock);
+
+	return r = 0;
+
+out:
+	mutex_unlock(&ddata->lock);
+	return true;
+}
+
+static struct omap_dss_driver panel_dvi_driver = {
+	.probe		= panel_dvi_probe,
+	.remove		= __exit_p(panel_dvi_remove),
+
+	.enable		= panel_dvi_enable,
+	.disable	= panel_dvi_disable,
+	.suspend	= panel_dvi_suspend,
+	.resume		= panel_dvi_resume,
+
+	.set_timings	= panel_dvi_set_timings,
+	.get_timings	= panel_dvi_get_timings,
+	.check_timings	= panel_dvi_check_timings,
+
+	.read_edid	= panel_dvi_read_edid,
+	.detect		= panel_dvi_detect,
+
+	.driver         = {
+		.name   = "dvi",
+		.owner  = THIS_MODULE,
+	},
+};
+
+static int __init panel_dvi_init(void)
+{
+	return omap_dss_register_driver(&panel_dvi_driver);
+}
+
+static void __exit panel_dvi_exit(void)
+{
+	omap_dss_unregister_driver(&panel_dvi_driver);
+}
+
+module_init(panel_dvi_init);
+module_exit(panel_dvi_exit);
+MODULE_LICENSE("GPL");
diff --git a/include/video/omap-panel-dvi.h b/include/video/omap-panel-dvi.h
new file mode 100644
index 0000000..87ad567
--- /dev/null
+++ b/include/video/omap-panel-dvi.h
@@ -0,0 +1,37 @@
+/*
+ * Header for DVI output driver
+ *
+ * Copyright (C) 2011 Texas Instruments Inc
+ * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __OMAP_PANEL_DVI_H
+#define __OMAP_PANEL_DVI_H
+
+struct omap_dss_device;
+
+/**
+ * struct panel_dvi_platform_data - panel driver configuration data
+ * @platform_enable: platform specific panel enable function
+ * @platform_disable: platform specific panel disable function
+ * @i2c_bus_num: i2c bus id for the panel
+ */
+struct panel_dvi_platform_data {
+	int (*platform_enable)(struct omap_dss_device *dssdev);
+	void (*platform_disable)(struct omap_dss_device *dssdev);
+	u16 i2c_bus_num;
+};
+
+#endif /* __OMAP_PANEL_DVI_H */
-- 
1.7.4.1


^ permalink raw reply related

* [PATCHv2 11/15] OMAP: use dvi panel driver instead of generic-dpi
From: Tomi Valkeinen @ 2011-09-12  9:13 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1315818818-18733-1-git-send-email-tomi.valkeinen@ti.com>

Multiple OMAP3/4 boards have a DVI framer output. This patch makes the
boards use the new panel-dvi driver, instead of the panel-generic-dpi
driver.

Separate drivers for fixed size panels and DVI framer gives us cleaner
driver code.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 arch/arm/mach-omap2/board-3430sdp.c      |    7 +++----
 arch/arm/mach-omap2/board-am3517evm.c    |    6 +++---
 arch/arm/mach-omap2/board-cm-t35.c       |    6 +++---
 arch/arm/mach-omap2/board-devkit8000.c   |    6 +++---
 arch/arm/mach-omap2/board-igep0020.c     |    7 +++----
 arch/arm/mach-omap2/board-omap3beagle.c  |    7 +++----
 arch/arm/mach-omap2/board-omap3evm.c     |    7 +++----
 arch/arm/mach-omap2/board-omap3stalker.c |    6 +++---
 arch/arm/mach-omap2/board-omap4panda.c   |    7 +++----
 arch/arm/mach-omap2/board-overo.c        |    6 +++---
 10 files changed, 30 insertions(+), 35 deletions(-)

diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index bd600cf..18c4d19 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -37,7 +37,7 @@
 #include <plat/dma.h>
 #include <plat/gpmc.h>
 #include <video/omapdss.h>
-#include <video/omap-panel-generic-dpi.h>
+#include <video/omap-panel-dvi.h>
 
 #include <plat/gpmc-smc91x.h>
 
@@ -186,8 +186,7 @@ static struct omap_dss_device sdp3430_lcd_device = {
 	.platform_disable	= sdp3430_panel_disable_lcd,
 };
 
-static struct panel_generic_dpi_data dvi_panel = {
-	.name			= "generic",
+static struct panel_dvi_platform_data dvi_panel = {
 	.platform_enable	= sdp3430_panel_enable_dvi,
 	.platform_disable	= sdp3430_panel_disable_dvi,
 };
@@ -195,7 +194,7 @@ static struct panel_generic_dpi_data dvi_panel = {
 static struct omap_dss_device sdp3430_dvi_device = {
 	.name			= "dvi",
 	.type			= OMAP_DISPLAY_TYPE_DPI,
-	.driver_name		= "generic_dpi_panel",
+	.driver_name		= "dvi",
 	.data			= &dvi_panel,
 	.phy.dpi.data_lines	= 24,
 };
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
index f3006c3..9a68ef5 100644
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -36,6 +36,7 @@
 #include <plat/usb.h>
 #include <video/omapdss.h>
 #include <video/omap-panel-generic-dpi.h>
+#include <video/omap-panel-dvi.h>
 
 #include "mux.h"
 #include "control.h"
@@ -333,8 +334,7 @@ static void am3517_evm_panel_disable_dvi(struct omap_dss_device *dssdev)
 	dvi_enabled = 0;
 }
 
-static struct panel_generic_dpi_data dvi_panel = {
-	.name			= "generic",
+static struct panel_dvi_platform_data dvi_panel = {
 	.platform_enable	= am3517_evm_panel_enable_dvi,
 	.platform_disable	= am3517_evm_panel_disable_dvi,
 };
@@ -342,7 +342,7 @@ static struct panel_generic_dpi_data dvi_panel = {
 static struct omap_dss_device am3517_evm_dvi_device = {
 	.type			= OMAP_DISPLAY_TYPE_DPI,
 	.name			= "dvi",
-	.driver_name		= "generic_dpi_panel",
+	.driver_name		= "dvi",
 	.data			= &dvi_panel,
 	.phy.dpi.data_lines	= 24,
 };
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index 3af8aab..2d112bf 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -43,6 +43,7 @@
 #include <plat/usb.h>
 #include <video/omapdss.h>
 #include <video/omap-panel-generic-dpi.h>
+#include <video/omap-panel-dvi.h>
 #include <plat/mcspi.h>
 
 #include <mach/hardware.h>
@@ -242,8 +243,7 @@ static struct omap_dss_device cm_t35_lcd_device = {
 	.phy.dpi.data_lines	= 18,
 };
 
-static struct panel_generic_dpi_data dvi_panel = {
-	.name			= "generic",
+static struct panel_dvi_platform_data dvi_panel = {
 	.platform_enable	= cm_t35_panel_enable_dvi,
 	.platform_disable	= cm_t35_panel_disable_dvi,
 };
@@ -251,7 +251,7 @@ static struct panel_generic_dpi_data dvi_panel = {
 static struct omap_dss_device cm_t35_dvi_device = {
 	.name			= "dvi",
 	.type			= OMAP_DISPLAY_TYPE_DPI,
-	.driver_name		= "generic_dpi_panel",
+	.driver_name		= "dvi",
 	.data			= &dvi_panel,
 	.phy.dpi.data_lines	= 24,
 };
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index da5057e..44da207 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -47,6 +47,7 @@
 #include <plat/usb.h>
 #include <video/omapdss.h>
 #include <video/omap-panel-generic-dpi.h>
+#include <video/omap-panel-dvi.h>
 
 #include <plat/mcspi.h>
 #include <linux/input/matrix_keypad.h>
@@ -152,8 +153,7 @@ static struct omap_dss_device devkit8000_lcd_device = {
 	.phy.dpi.data_lines     = 24,
 };
 
-static struct panel_generic_dpi_data dvi_panel = {
-	.name			= "generic",
+static struct panel_dvi_platform_data dvi_panel = {
 	.platform_enable        = devkit8000_panel_enable_dvi,
 	.platform_disable       = devkit8000_panel_disable_dvi,
 };
@@ -161,7 +161,7 @@ static struct panel_generic_dpi_data dvi_panel = {
 static struct omap_dss_device devkit8000_dvi_device = {
 	.name                   = "dvi",
 	.type                   = OMAP_DISPLAY_TYPE_DPI,
-	.driver_name            = "generic_dpi_panel",
+	.driver_name            = "dvi",
 	.data			= &dvi_panel,
 	.phy.dpi.data_lines     = 24,
 };
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 35be778..9fda8d8 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -32,7 +32,7 @@
 #include <plat/gpmc.h>
 #include <plat/usb.h>
 #include <video/omapdss.h>
-#include <video/omap-panel-generic-dpi.h>
+#include <video/omap-panel-dvi.h>
 #include <plat/onenand.h>
 
 #include "mux.h"
@@ -455,8 +455,7 @@ static void igep2_disable_dvi(struct omap_dss_device *dssdev)
 	gpio_direction_output(IGEP2_GPIO_DVI_PUP, 0);
 }
 
-static struct panel_generic_dpi_data dvi_panel = {
-	.name			= "generic",
+static struct panel_dvi_platform_data dvi_panel = {
 	.platform_enable	= igep2_enable_dvi,
 	.platform_disable	= igep2_disable_dvi,
 };
@@ -464,7 +463,7 @@ static struct panel_generic_dpi_data dvi_panel = {
 static struct omap_dss_device igep2_dvi_device = {
 	.type			= OMAP_DISPLAY_TYPE_DPI,
 	.name			= "dvi",
-	.driver_name		= "generic_dpi_panel",
+	.driver_name		= "dvi",
 	.data			= &dvi_panel,
 	.phy.dpi.data_lines	= 24,
 };
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 3ae16b4..26bc860 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -42,7 +42,7 @@
 #include <plat/board.h>
 #include <plat/common.h>
 #include <video/omapdss.h>
-#include <video/omap-panel-generic-dpi.h>
+#include <video/omap-panel-dvi.h>
 #include <plat/gpmc.h>
 #include <plat/nand.h>
 #include <plat/usb.h>
@@ -203,8 +203,7 @@ static void beagle_disable_dvi(struct omap_dss_device *dssdev)
 		gpio_set_value(dssdev->reset_gpio, 0);
 }
 
-static struct panel_generic_dpi_data dvi_panel = {
-	.name = "generic",
+static struct panel_dvi_platform_data dvi_panel = {
 	.platform_enable = beagle_enable_dvi,
 	.platform_disable = beagle_disable_dvi,
 };
@@ -212,7 +211,7 @@ static struct panel_generic_dpi_data dvi_panel = {
 static struct omap_dss_device beagle_dvi_device = {
 	.type = OMAP_DISPLAY_TYPE_DPI,
 	.name = "dvi",
-	.driver_name = "generic_dpi_panel",
+	.driver_name = "dvi",
 	.data = &dvi_panel,
 	.phy.dpi.data_lines = 24,
 	.reset_gpio = -EINVAL,
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index c452b3f..82142c5 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -45,7 +45,7 @@
 #include <plat/common.h>
 #include <plat/mcspi.h>
 #include <video/omapdss.h>
-#include <video/omap-panel-generic-dpi.h>
+#include <video/omap-panel-dvi.h>
 
 #include "mux.h"
 #include "sdram-micron-mt46h32m32lf-6.h"
@@ -247,8 +247,7 @@ static void omap3_evm_disable_dvi(struct omap_dss_device *dssdev)
 	dvi_enabled = 0;
 }
 
-static struct panel_generic_dpi_data dvi_panel = {
-	.name			= "generic",
+static struct panel_dvi_platform_data dvi_panel = {
 	.platform_enable	= omap3_evm_enable_dvi,
 	.platform_disable	= omap3_evm_disable_dvi,
 };
@@ -256,7 +255,7 @@ static struct panel_generic_dpi_data dvi_panel = {
 static struct omap_dss_device omap3_evm_dvi_device = {
 	.name			= "dvi",
 	.type			= OMAP_DISPLAY_TYPE_DPI,
-	.driver_name		= "generic_dpi_panel",
+	.driver_name		= "dvi",
 	.data			= &dvi_panel,
 	.phy.dpi.data_lines	= 24,
 };
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index 8e10498..8ab99f1 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -41,6 +41,7 @@
 #include <plat/usb.h>
 #include <video/omapdss.h>
 #include <video/omap-panel-generic-dpi.h>
+#include <video/omap-panel-dvi.h>
 
 #include <plat/mcspi.h>
 #include <linux/input/matrix_keypad.h>
@@ -179,8 +180,7 @@ static void omap3_stalker_disable_dvi(struct omap_dss_device *dssdev)
 	dvi_enabled = 0;
 }
 
-static struct panel_generic_dpi_data dvi_panel = {
-	.name			= "generic",
+static struct panel_dvi_platform_data dvi_panel = {
 	.platform_enable	= omap3_stalker_enable_dvi,
 	.platform_disable	= omap3_stalker_disable_dvi,
 };
@@ -188,7 +188,7 @@ static struct panel_generic_dpi_data dvi_panel = {
 static struct omap_dss_device omap3_stalker_dvi_device = {
 	.name			= "dvi",
 	.type			= OMAP_DISPLAY_TYPE_DPI,
-	.driver_name		= "generic_dpi_panel",
+	.driver_name		= "dvi",
 	.data			= &dvi_panel,
 	.phy.dpi.data_lines	= 24,
 };
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 9aaa960..c35384e 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -40,7 +40,7 @@
 #include <plat/common.h>
 #include <plat/usb.h>
 #include <plat/mmc.h>
-#include <video/omap-panel-generic-dpi.h>
+#include <video/omap-panel-dvi.h>
 
 #include "hsmmc.h"
 #include "control.h"
@@ -455,8 +455,7 @@ static void omap4_panda_disable_dvi(struct omap_dss_device *dssdev)
 }
 
 /* Using generic display panel */
-static struct panel_generic_dpi_data omap4_dvi_panel = {
-	.name			= "generic",
+static struct panel_dvi_platform_data omap4_dvi_panel = {
 	.platform_enable	= omap4_panda_enable_dvi,
 	.platform_disable	= omap4_panda_disable_dvi,
 };
@@ -464,7 +463,7 @@ static struct panel_generic_dpi_data omap4_dvi_panel = {
 struct omap_dss_device omap4_panda_dvi_device = {
 	.type			= OMAP_DISPLAY_TYPE_DPI,
 	.name			= "dvi",
-	.driver_name		= "generic_dpi_panel",
+	.driver_name		= "dvi",
 	.data			= &omap4_dvi_panel,
 	.phy.dpi.data_lines	= 24,
 	.reset_gpio		= PANDA_DVI_TFP410_POWER_DOWN_GPIO,
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index f949a99..06064d5 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -46,6 +46,7 @@
 #include <plat/common.h>
 #include <video/omapdss.h>
 #include <video/omap-panel-generic-dpi.h>
+#include <video/omap-panel-dvi.h>
 #include <plat/gpmc.h>
 #include <mach/hardware.h>
 #include <plat/nand.h>
@@ -182,8 +183,7 @@ static void overo_panel_disable_dvi(struct omap_dss_device *dssdev)
 	dvi_enabled = 0;
 }
 
-static struct panel_generic_dpi_data dvi_panel = {
-	.name			= "generic",
+static struct panel_dvi_platform_data dvi_panel = {
 	.platform_enable	= overo_panel_enable_dvi,
 	.platform_disable	= overo_panel_disable_dvi,
 };
@@ -191,7 +191,7 @@ static struct panel_generic_dpi_data dvi_panel = {
 static struct omap_dss_device overo_dvi_device = {
 	.name			= "dvi",
 	.type			= OMAP_DISPLAY_TYPE_DPI,
-	.driver_name		= "generic_dpi_panel",
+	.driver_name		= "dvi",
 	.data			= &dvi_panel,
 	.phy.dpi.data_lines	= 24,
 };
-- 
1.7.4.1


^ permalink raw reply related

* [PATCHv2 12/15] OMAP: stalker: Remove LCD device from board file
From: Tomi Valkeinen @ 2011-09-12  9:13 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: archit, Tomi Valkeinen, Jason Lam
In-Reply-To: <1315818818-18733-1-git-send-email-tomi.valkeinen@ti.com>

OMAP3 Stalker board has definitions for LCD, but uses the generic driver
without any information what kind of LCD it has. The board should use a
particular panel type from panel-generic-dpi driver, not the generic
one.

As I haven't gotten response the signer-off of stalker board about the
issue, this patch removes the LCD support from the board file. This will
allow us to clean up the panel-generic-dpi driver and make it support
only fixed size panels.

CC: Jason Lam <lzg@ema-tech.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 arch/arm/mach-omap2/board-omap3stalker.c |   34 ------------------------------
 1 files changed, 0 insertions(+), 34 deletions(-)

diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index 8ab99f1..106a2ba 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -108,39 +108,6 @@ static void __init omap3_stalker_display_init(void)
 	return;
 }
 
-static int omap3_stalker_enable_lcd(struct omap_dss_device *dssdev)
-{
-	if (dvi_enabled) {
-		printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
-		return -EINVAL;
-	}
-	gpio_set_value(DSS_ENABLE_GPIO, 1);
-	gpio_set_value(LCD_PANEL_BKLIGHT_GPIO, 1);
-	lcd_enabled = 1;
-	return 0;
-}
-
-static void omap3_stalker_disable_lcd(struct omap_dss_device *dssdev)
-{
-	gpio_set_value(DSS_ENABLE_GPIO, 0);
-	gpio_set_value(LCD_PANEL_BKLIGHT_GPIO, 0);
-	lcd_enabled = 0;
-}
-
-static struct panel_generic_dpi_data lcd_panel = {
-	.name			= "generic",
-	.platform_enable	= omap3_stalker_enable_lcd,
-	.platform_disable	= omap3_stalker_disable_lcd,
-};
-
-static struct omap_dss_device omap3_stalker_lcd_device = {
-	.name			= "lcd",
-	.driver_name		= "generic_dpi_panel",
-	.data			= &lcd_panel,
-	.phy.dpi.data_lines	= 24,
-	.type			= OMAP_DISPLAY_TYPE_DPI,
-};
-
 static int omap3_stalker_enable_tv(struct omap_dss_device *dssdev)
 {
 	return 0;
@@ -194,7 +161,6 @@ static struct omap_dss_device omap3_stalker_dvi_device = {
 };
 
 static struct omap_dss_device *omap3_stalker_dss_devices[] = {
-	&omap3_stalker_lcd_device,
 	&omap3_stalker_tv_device,
 	&omap3_stalker_dvi_device,
 };
-- 
1.7.4.1


^ permalink raw reply related

* [PATCHv2 13/15] OMAP: DSS2: panel-generic-dpi: remove "generic" panel
From: Tomi Valkeinen @ 2011-09-12  9:13 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1315818818-18733-1-git-send-email-tomi.valkeinen@ti.com>

Remove the "generic" panel config entry, which is not used.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap2/displays/panel-generic-dpi.c |   24 ----------------------
 1 files changed, 0 insertions(+), 24 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index b401304..e0399c3 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -58,30 +58,6 @@ struct panel_config {
 
 /* Panel configurations */
 static struct panel_config generic_dpi_panels[] = {
-	/* Generic Panel */
-	{
-		{
-			.x_res		= 640,
-			.y_res		= 480,
-
-			.pixel_clock	= 23500,
-
-			.hfp		= 48,
-			.hsw		= 32,
-			.hbp		= 80,
-
-			.vfp		= 3,
-			.vsw		= 4,
-			.vbp		= 7,
-		},
-		.acbi			= 0x0,
-		.acb			= 0x0,
-		.config			= OMAP_DSS_LCD_TFT,
-		.power_on_delay		= 0,
-		.power_off_delay	= 0,
-		.name			= "generic",
-	},
-
 	/* Sharp LQ043T1DG01 */
 	{
 		{
-- 
1.7.4.1


^ permalink raw reply related

* [PATCHv2 14/15] OMAP: Panda, Beagle, Overo: DVI: Add i2c_bus_num
From: Tomi Valkeinen @ 2011-09-12  9:13 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1315818818-18733-1-git-send-email-tomi.valkeinen@ti.com>

Add i2c bus number for DVI output. The driver uses this to detect if a
panel is connected and to read EDID.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 arch/arm/mach-omap2/board-omap3beagle.c |    1 +
 arch/arm/mach-omap2/board-omap4panda.c  |    1 +
 arch/arm/mach-omap2/board-overo.c       |    1 +
 3 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 26bc860..742ac45 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -206,6 +206,7 @@ static void beagle_disable_dvi(struct omap_dss_device *dssdev)
 static struct panel_dvi_platform_data dvi_panel = {
 	.platform_enable = beagle_enable_dvi,
 	.platform_disable = beagle_disable_dvi,
+	.i2c_bus_num = 3,
 };
 
 static struct omap_dss_device beagle_dvi_device = {
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index c35384e..a38ed273 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -458,6 +458,7 @@ static void omap4_panda_disable_dvi(struct omap_dss_device *dssdev)
 static struct panel_dvi_platform_data omap4_dvi_panel = {
 	.platform_enable	= omap4_panda_enable_dvi,
 	.platform_disable	= omap4_panda_disable_dvi,
+	.i2c_bus_num = 3,
 };
 
 struct omap_dss_device omap4_panda_dvi_device = {
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 06064d5..da94376 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -186,6 +186,7 @@ static void overo_panel_disable_dvi(struct omap_dss_device *dssdev)
 static struct panel_dvi_platform_data dvi_panel = {
 	.platform_enable	= overo_panel_enable_dvi,
 	.platform_disable	= overo_panel_disable_dvi,
+	.i2c_bus_num		= 3,
 };
 
 static struct omap_dss_device overo_dvi_device = {
-- 
1.7.4.1


^ permalink raw reply related

* [PATCHv2 15/15] OMAPFB: find best mode from edid
From: Tomi Valkeinen @ 2011-09-12  9:13 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1315818818-18733-1-git-send-email-tomi.valkeinen@ti.com>

Use the new read_edid() function to get EDID information from the
display (when available), and use the information to use a suitable mode
at initialization time.

Hot-plug is not yet supported, so the timings selected at init time will
stay even if the monitor would be changed.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap2/omapfb/omapfb-main.c |  109 +++++++++++++++++++++++++++---
 1 files changed, 99 insertions(+), 10 deletions(-)

diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index cd2cae8e..c84cc29 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -2276,6 +2276,87 @@ static int omapfb_parse_def_modes(struct omapfb2_device *fbdev)
 	return r;
 }
 
+static void fb_videomode_to_omap_timings(struct fb_videomode *m,
+		struct omap_video_timings *t)
+{
+	t->x_res = m->xres;
+	t->y_res = m->yres;
+	t->pixel_clock = PICOS2KHZ(m->pixclock);
+	t->hsw = m->hsync_len;
+	t->hfp = m->right_margin;
+	t->hbp = m->left_margin;
+	t->vsw = m->vsync_len;
+	t->vfp = m->lower_margin;
+	t->vbp = m->upper_margin;
+}
+
+static int omapfb_find_best_mode(struct omap_dss_device *display,
+		struct omap_video_timings *timings)
+{
+	struct fb_monspecs *specs;
+	u8 *edid;
+	int r, i, best_xres, best_idx, len;
+
+	if (!display->driver->read_edid)
+		return -ENODEV;
+
+	len = 0x80 * 2;
+	edid = kmalloc(len, GFP_KERNEL);
+
+	r = display->driver->read_edid(display, edid, len);
+	if (r < 0)
+		goto err1;
+
+	specs = kzalloc(sizeof(*specs), GFP_KERNEL);
+
+	fb_edid_to_monspecs(edid, specs);
+
+	if (edid[126] > 0)
+		fb_edid_add_monspecs(edid + 0x80, specs);
+
+	best_xres = 0;
+	best_idx = -1;
+
+	for (i = 0; i < specs->modedb_len; ++i) {
+		struct fb_videomode *m;
+		struct omap_video_timings t;
+
+		m = &specs->modedb[i];
+
+		if (m->pixclock = 0)
+			continue;
+
+		/* skip repeated pixel modes */
+		if (m->xres = 2880 || m->xres = 1440)
+			continue;
+
+		fb_videomode_to_omap_timings(m, &t);
+
+		r = display->driver->check_timings(display, &t);
+		if (r = 0 && best_xres < m->xres) {
+			best_xres = m->xres;
+			best_idx = i;
+		}
+	}
+
+	if (best_xres = 0) {
+		r = -ENOENT;
+		goto err2;
+	}
+
+	fb_videomode_to_omap_timings(&specs->modedb[best_idx], timings);
+
+	r = 0;
+
+err2:
+	fb_destroy_modedb(specs->modedb);
+	kfree(specs);
+err1:
+	kfree(edid);
+
+	return r;
+}
+
 static int omapfb_init_display(struct omapfb2_device *fbdev,
 		struct omap_dss_device *dssdev)
 {
@@ -2404,9 +2485,27 @@ static int omapfb_probe(struct platform_device *pdev)
 	for (i = 0; i < fbdev->num_managers; i++)
 		fbdev->managers[i] = omap_dss_get_overlay_manager(i);
 
+	/* gfx overlay should be the default one. find a display
+	 * connected to that, and use it as default display */
+	ovl = omap_dss_get_overlay(0);
+	if (ovl->manager && ovl->manager->device) {
+		def_display = ovl->manager->device;
+	} else {
+		dev_warn(&pdev->dev, "cannot find default display\n");
+		def_display = NULL;
+	}
+
 	if (def_mode && strlen(def_mode) > 0) {
 		if (omapfb_parse_def_modes(fbdev))
 			dev_warn(&pdev->dev, "cannot parse default modes\n");
+	} else if (def_display && def_display->driver->set_timings &&
+			def_display->driver->check_timings) {
+		struct omap_video_timings t;
+
+		r = omapfb_find_best_mode(def_display, &t);
+
+		if (r = 0)
+			def_display->driver->set_timings(def_display, &t);
 	}
 
 	r = omapfb_create_framebuffers(fbdev);
@@ -2423,16 +2522,6 @@ static int omapfb_probe(struct platform_device *pdev)
 
 	DBG("mgr->apply'ed\n");
 
-	/* gfx overlay should be the default one. find a display
-	 * connected to that, and use it as default display */
-	ovl = omap_dss_get_overlay(0);
-	if (ovl->manager && ovl->manager->device) {
-		def_display = ovl->manager->device;
-	} else {
-		dev_warn(&pdev->dev, "cannot find default display\n");
-		def_display = NULL;
-	}
-
 	if (def_display) {
 		r = omapfb_init_display(fbdev, def_display);
 		if (r) {
-- 
1.7.4.1


^ permalink raw reply related

* Re: [PATCHv2 14/15] OMAP: Panda, Beagle, Overo: DVI: Add i2c_bus_num
From: Enric Balletbò i Serra @ 2011-09-12  9:58 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev, archit
In-Reply-To: <1315818818-18733-15-git-send-email-tomi.valkeinen@ti.com>

2011/9/12 Tomi Valkeinen <tomi.valkeinen@ti.com>:
> Add i2c bus number for DVI output. The driver uses this to detect if a
> panel is connected and to read EDID.
>
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> ---
>  arch/arm/mach-omap2/board-omap3beagle.c |    1 +
>  arch/arm/mach-omap2/board-omap4panda.c  |    1 +
>  arch/arm/mach-omap2/board-overo.c       |    1 +
>  3 files changed, 3 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
> index 26bc860..742ac45 100644
> --- a/arch/arm/mach-omap2/board-omap3beagle.c
> +++ b/arch/arm/mach-omap2/board-omap3beagle.c
> @@ -206,6 +206,7 @@ static void beagle_disable_dvi(struct omap_dss_device *dssdev)
>  static struct panel_dvi_platform_data dvi_panel = {
>        .platform_enable = beagle_enable_dvi,
>        .platform_disable = beagle_disable_dvi,
> +       .i2c_bus_num = 3,
>  };
>
>  static struct omap_dss_device beagle_dvi_device = {
> diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
> index c35384e..a38ed273 100644
> --- a/arch/arm/mach-omap2/board-omap4panda.c
> +++ b/arch/arm/mach-omap2/board-omap4panda.c
> @@ -458,6 +458,7 @@ static void omap4_panda_disable_dvi(struct omap_dss_device *dssdev)
>  static struct panel_dvi_platform_data omap4_dvi_panel = {
>        .platform_enable        = omap4_panda_enable_dvi,
>        .platform_disable       = omap4_panda_disable_dvi,
> +       .i2c_bus_num = 3,
>  };
>
>  struct omap_dss_device omap4_panda_dvi_device = {
> diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
> index 06064d5..da94376 100644
> --- a/arch/arm/mach-omap2/board-overo.c
> +++ b/arch/arm/mach-omap2/board-overo.c
> @@ -186,6 +186,7 @@ static void overo_panel_disable_dvi(struct omap_dss_device *dssdev)
>  static struct panel_dvi_platform_data dvi_panel = {
>        .platform_enable        = overo_panel_enable_dvi,
>        .platform_disable       = overo_panel_disable_dvi,
> +       .i2c_bus_num            = 3,
>  };
>
>  static struct omap_dss_device overo_dvi_device = {
> --
> 1.7.4.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

Please, can also include the same modification for IGEP v2 board
(arch/arm/mach-omap2/board-igep0020.c) ?

Best regards,
   Enric

^ permalink raw reply

* Re: [PATCHv2 14/15] OMAP: Panda, Beagle, Overo: DVI: Add
From: Tomi Valkeinen @ 2011-09-12 10:17 UTC (permalink / raw)
  To: Enric Balletbò i Serra; +Cc: linux-omap, linux-fbdev, archit
In-Reply-To: <CAFqH_53ttom-c75NihgmMsckp4RQTpskXhYjAEAee2LWsHXW0g@mail.gmail.com>

On Mon, 2011-09-12 at 11:58 +0200, Enric Balletbò i Serra wrote:
> 2011/9/12 Tomi Valkeinen <tomi.valkeinen@ti.com>:
> > Add i2c bus number for DVI output. The driver uses this to detect if a
> > panel is connected and to read EDID.
> >
> > Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> > ---
> >  arch/arm/mach-omap2/board-omap3beagle.c |    1 +
> >  arch/arm/mach-omap2/board-omap4panda.c  |    1 +
> >  arch/arm/mach-omap2/board-overo.c       |    1 +
> >  3 files changed, 3 insertions(+), 0 deletions(-)
> >
> > diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
> > index 26bc860..742ac45 100644
> > --- a/arch/arm/mach-omap2/board-omap3beagle.c
> > +++ b/arch/arm/mach-omap2/board-omap3beagle.c
> > @@ -206,6 +206,7 @@ static void beagle_disable_dvi(struct omap_dss_device *dssdev)
> >  static struct panel_dvi_platform_data dvi_panel = {
> >        .platform_enable = beagle_enable_dvi,
> >        .platform_disable = beagle_disable_dvi,
> > +       .i2c_bus_num = 3,
> >  };
> >
> >  static struct omap_dss_device beagle_dvi_device = {
> > diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
> > index c35384e..a38ed273 100644
> > --- a/arch/arm/mach-omap2/board-omap4panda.c
> > +++ b/arch/arm/mach-omap2/board-omap4panda.c
> > @@ -458,6 +458,7 @@ static void omap4_panda_disable_dvi(struct omap_dss_device *dssdev)
> >  static struct panel_dvi_platform_data omap4_dvi_panel = {
> >        .platform_enable        = omap4_panda_enable_dvi,
> >        .platform_disable       = omap4_panda_disable_dvi,
> > +       .i2c_bus_num = 3,
> >  };
> >
> >  struct omap_dss_device omap4_panda_dvi_device = {
> > diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
> > index 06064d5..da94376 100644
> > --- a/arch/arm/mach-omap2/board-overo.c
> > +++ b/arch/arm/mach-omap2/board-overo.c
> > @@ -186,6 +186,7 @@ static void overo_panel_disable_dvi(struct omap_dss_device *dssdev)
> >  static struct panel_dvi_platform_data dvi_panel = {
> >        .platform_enable        = overo_panel_enable_dvi,
> >        .platform_disable       = overo_panel_disable_dvi,
> > +       .i2c_bus_num            = 3,
> >  };
> >
> >  static struct omap_dss_device overo_dvi_device = {
> > --
> > 1.7.4.1
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >
> 
> Please, can also include the same modification for IGEP v2 board
> (arch/arm/mach-omap2/board-igep0020.c) ?

Sure. You have tested that the i2c bus is 3 and it works?

 Tomi



^ permalink raw reply

* Re: [PATCHv2 8/8] OMAP: DSS2: HDMI: improve hdmi output enable
From: Tomi Valkeinen @ 2011-09-12 11:06 UTC (permalink / raw)
  To: Archit Taneja
  Cc: linux-omap@vger.kernel.org, linux-fbdev@vger.kernel.org,
	K, Mythri P
In-Reply-To: <4E6DE68F.3020809@ti.com>

On Mon, 2011-09-12 at 16:31 +0530, Archit Taneja wrote:
> On Monday 12 September 2011 02:42 PM, Valkeinen, Tomi wrote:
> > Enabling HDMI output often causes sync lost errors, and almost always
> > causes timeout errors being printed from dispc_mgr_enable_digit_out().
> >
> > The sync lost problem seems to go lessen greatly if we first enable the
> > HDMI output, and only then enable the DISPC output. However, as this is
> > only based on observations, the fix may not be perfect as the problem
> > may lie somewhere else. Nevertheless, HDMI works better with this patch.
> >
> > This will also fix the dispc's dispc_mgr_enable_digit_out(), as the code
> > waits for two VSYNCs after enabling the output. If the HDMI output is
> > disabled (as it was previously), there are no VSYNCs and
> > dispc_mgr_enable_digit_out() will print timeout errors.
> >
> > Cc: Mythri P K<mythripk@ti.com>
> > Signed-off-by: Tomi Valkeinen<tomi.valkeinen@ti.com>
> > ---
> >   drivers/video/omap2/dss/hdmi.c |    4 ++--
> >   1 files changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
> > index 4752137..06a78b2 100644
> > --- a/drivers/video/omap2/dss/hdmi.c
> > +++ b/drivers/video/omap2/dss/hdmi.c
> > @@ -529,10 +529,10 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
> >   	dispc_set_digit_size(dssdev->panel.timings.x_res,
> >   			dssdev->panel.timings.y_res);
> >
> > -	dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, 1);
> > -
> >   	hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 1);
> >
> > +	dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, 1);
> > +
> 
> What content would HDMI push out till the time DIGIT is enabled? It 
> might be interesting to put some milliseconds of delay here and see what 
> happens.

I guess HDMI works independently of DISPC. So HDMI will output whatever
is in the video port from DISPC to HDMI, regardless of what DISPC does.
My guess is it's either random bits or, more probably, zeroes.

I think this way is the same as used for VENC: first we configure and
enable VENC, then we enable DISPC digit output.

 Tomi



^ permalink raw reply

* Re: [PATCHv2 8/8] OMAP: DSS2: HDMI: improve hdmi output enable
From: Archit Taneja @ 2011-09-12 11:13 UTC (permalink / raw)
  To: Valkeinen, Tomi
  Cc: linux-omap@vger.kernel.org, linux-fbdev@vger.kernel.org,
	K, Mythri P
In-Reply-To: <1315818773-18660-9-git-send-email-tomi.valkeinen@ti.com>

On Monday 12 September 2011 02:42 PM, Valkeinen, Tomi wrote:
> Enabling HDMI output often causes sync lost errors, and almost always
> causes timeout errors being printed from dispc_mgr_enable_digit_out().
>
> The sync lost problem seems to go lessen greatly if we first enable the
> HDMI output, and only then enable the DISPC output. However, as this is
> only based on observations, the fix may not be perfect as the problem
> may lie somewhere else. Nevertheless, HDMI works better with this patch.
>
> This will also fix the dispc's dispc_mgr_enable_digit_out(), as the code
> waits for two VSYNCs after enabling the output. If the HDMI output is
> disabled (as it was previously), there are no VSYNCs and
> dispc_mgr_enable_digit_out() will print timeout errors.
>
> Cc: Mythri P K<mythripk@ti.com>
> Signed-off-by: Tomi Valkeinen<tomi.valkeinen@ti.com>
> ---
>   drivers/video/omap2/dss/hdmi.c |    4 ++--
>   1 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
> index 4752137..06a78b2 100644
> --- a/drivers/video/omap2/dss/hdmi.c
> +++ b/drivers/video/omap2/dss/hdmi.c
> @@ -529,10 +529,10 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
>   	dispc_set_digit_size(dssdev->panel.timings.x_res,
>   			dssdev->panel.timings.y_res);
>
> -	dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, 1);
> -
>   	hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 1);
>
> +	dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, 1);
> +

What content would HDMI push out till the time DIGIT is enabled? It 
might be interesting to put some milliseconds of delay here and see what 
happens.

Archit

>   	return 0;
>   err:
>   	hdmi_runtime_put();


^ permalink raw reply

* Re: [PATCHv2 14/15] OMAP: Panda, Beagle, Overo: DVI: Add i2c_bus_num
From: Enric Balletbò i Serra @ 2011-09-12 11:13 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev, archit
In-Reply-To: <1315822645.2177.23.camel@deskari>

2011/9/12 Tomi Valkeinen <tomi.valkeinen@ti.com>:
> On Mon, 2011-09-12 at 11:58 +0200, Enric Balletbò i Serra wrote:
>> 2011/9/12 Tomi Valkeinen <tomi.valkeinen@ti.com>:
>> > Add i2c bus number for DVI output. The driver uses this to detect if a
>> > panel is connected and to read EDID.
>> >
>> > Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
>> > ---
>> >  arch/arm/mach-omap2/board-omap3beagle.c |    1 +
>> >  arch/arm/mach-omap2/board-omap4panda.c  |    1 +
>> >  arch/arm/mach-omap2/board-overo.c       |    1 +
>> >  3 files changed, 3 insertions(+), 0 deletions(-)
>> >
>> > diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
>> > index 26bc860..742ac45 100644
>> > --- a/arch/arm/mach-omap2/board-omap3beagle.c
>> > +++ b/arch/arm/mach-omap2/board-omap3beagle.c
>> > @@ -206,6 +206,7 @@ static void beagle_disable_dvi(struct omap_dss_device *dssdev)
>> >  static struct panel_dvi_platform_data dvi_panel = {
>> >        .platform_enable = beagle_enable_dvi,
>> >        .platform_disable = beagle_disable_dvi,
>> > +       .i2c_bus_num = 3,
>> >  };
>> >
>> >  static struct omap_dss_device beagle_dvi_device = {
>> > diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
>> > index c35384e..a38ed273 100644
>> > --- a/arch/arm/mach-omap2/board-omap4panda.c
>> > +++ b/arch/arm/mach-omap2/board-omap4panda.c
>> > @@ -458,6 +458,7 @@ static void omap4_panda_disable_dvi(struct omap_dss_device *dssdev)
>> >  static struct panel_dvi_platform_data omap4_dvi_panel = {
>> >        .platform_enable        = omap4_panda_enable_dvi,
>> >        .platform_disable       = omap4_panda_disable_dvi,
>> > +       .i2c_bus_num = 3,
>> >  };
>> >
>> >  struct omap_dss_device omap4_panda_dvi_device = {
>> > diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
>> > index 06064d5..da94376 100644
>> > --- a/arch/arm/mach-omap2/board-overo.c
>> > +++ b/arch/arm/mach-omap2/board-overo.c
>> > @@ -186,6 +186,7 @@ static void overo_panel_disable_dvi(struct omap_dss_device *dssdev)
>> >  static struct panel_dvi_platform_data dvi_panel = {
>> >        .platform_enable        = overo_panel_enable_dvi,
>> >        .platform_disable       = overo_panel_disable_dvi,
>> > +       .i2c_bus_num            = 3,
>> >  };
>> >
>> >  static struct omap_dss_device overo_dvi_device = {
>> > --
>> > 1.7.4.1
>> >
>> > --
>> > To unsubscribe from this list: send the line "unsubscribe linux-omap" in
>> > the body of a message to majordomo@vger.kernel.org
>> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> >
>>
>> Please, can also include the same modification for IGEP v2 board
>> (arch/arm/mach-omap2/board-igep0020.c) ?
>
> Sure. You have tested that the i2c bus is 3 and it works?

Yes, the i2c bus is 3 on IGEP v2 board and I'm just testing and seem is working.

>
>  Tomi
>
>
>

^ permalink raw reply

* Re: [PATCHv2 8/8] OMAP: DSS2: HDMI: improve hdmi output enable
From: Tomi Valkeinen @ 2011-09-12 11:29 UTC (permalink / raw)
  To: Archit Taneja
  Cc: linux-omap@vger.kernel.org, linux-fbdev@vger.kernel.org,
	K, Mythri P
In-Reply-To: <4E6DEBB6.6090703@ti.com>

On Mon, 2011-09-12 at 16:53 +0530, Archit Taneja wrote:
> On Monday 12 September 2011 04:36 PM, Valkeinen, Tomi wrote:
> > On Mon, 2011-09-12 at 16:31 +0530, Archit Taneja wrote:
> >> On Monday 12 September 2011 02:42 PM, Valkeinen, Tomi wrote:
> >>> Enabling HDMI output often causes sync lost errors, and almost always
> >>> causes timeout errors being printed from dispc_mgr_enable_digit_out().
> >>>
> >>> The sync lost problem seems to go lessen greatly if we first enable the
> >>> HDMI output, and only then enable the DISPC output. However, as this is
> >>> only based on observations, the fix may not be perfect as the problem
> >>> may lie somewhere else. Nevertheless, HDMI works better with this patch.
> >>>
> >>> This will also fix the dispc's dispc_mgr_enable_digit_out(), as the code
> >>> waits for two VSYNCs after enabling the output. If the HDMI output is
> >>> disabled (as it was previously), there are no VSYNCs and
> >>> dispc_mgr_enable_digit_out() will print timeout errors.
> >>>
> >>> Cc: Mythri P K<mythripk@ti.com>
> >>> Signed-off-by: Tomi Valkeinen<tomi.valkeinen@ti.com>
> >>> ---
> >>>    drivers/video/omap2/dss/hdmi.c |    4 ++--
> >>>    1 files changed, 2 insertions(+), 2 deletions(-)
> >>>
> >>> diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
> >>> index 4752137..06a78b2 100644
> >>> --- a/drivers/video/omap2/dss/hdmi.c
> >>> +++ b/drivers/video/omap2/dss/hdmi.c
> >>> @@ -529,10 +529,10 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
> >>>    	dispc_set_digit_size(dssdev->panel.timings.x_res,
> >>>    			dssdev->panel.timings.y_res);
> >>>
> >>> -	dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, 1);
> >>> -
> >>>    	hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 1);
> >>>
> >>> +	dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, 1);
> >>> +
> >>
> >> What content would HDMI push out till the time DIGIT is enabled? It
> >> might be interesting to put some milliseconds of delay here and see what
> >> happens.
> >
> > I guess HDMI works independently of DISPC. So HDMI will output whatever
> > is in the video port from DISPC to HDMI, regardless of what DISPC does.
> > My guess is it's either random bits or, more probably, zeroes.
> 
> Okay. I thought HDMI block may probe the video port's DE line or 
> something to check if it is pushing out valid content. However, with 
> this patch, we are more aligned with what we do in power_off(), i.e 
> first disable the manager and then disable HDMI.

Yep. But as I said in the desc, this is just based on my observations.
If this is the wrong way to enable tv-output, we should check whether
venc is also working the wrong way.

 Tomi



^ permalink raw reply

* Re: [PATCHv2 8/8] OMAP: DSS2: HDMI: improve hdmi output enable
From: Archit Taneja @ 2011-09-12 11:35 UTC (permalink / raw)
  To: Valkeinen, Tomi
  Cc: linux-omap@vger.kernel.org, linux-fbdev@vger.kernel.org,
	K, Mythri P
In-Reply-To: <1315825587.2177.27.camel@deskari>

On Monday 12 September 2011 04:36 PM, Valkeinen, Tomi wrote:
> On Mon, 2011-09-12 at 16:31 +0530, Archit Taneja wrote:
>> On Monday 12 September 2011 02:42 PM, Valkeinen, Tomi wrote:
>>> Enabling HDMI output often causes sync lost errors, and almost always
>>> causes timeout errors being printed from dispc_mgr_enable_digit_out().
>>>
>>> The sync lost problem seems to go lessen greatly if we first enable the
>>> HDMI output, and only then enable the DISPC output. However, as this is
>>> only based on observations, the fix may not be perfect as the problem
>>> may lie somewhere else. Nevertheless, HDMI works better with this patch.
>>>
>>> This will also fix the dispc's dispc_mgr_enable_digit_out(), as the code
>>> waits for two VSYNCs after enabling the output. If the HDMI output is
>>> disabled (as it was previously), there are no VSYNCs and
>>> dispc_mgr_enable_digit_out() will print timeout errors.
>>>
>>> Cc: Mythri P K<mythripk@ti.com>
>>> Signed-off-by: Tomi Valkeinen<tomi.valkeinen@ti.com>
>>> ---
>>>    drivers/video/omap2/dss/hdmi.c |    4 ++--
>>>    1 files changed, 2 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
>>> index 4752137..06a78b2 100644
>>> --- a/drivers/video/omap2/dss/hdmi.c
>>> +++ b/drivers/video/omap2/dss/hdmi.c
>>> @@ -529,10 +529,10 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
>>>    	dispc_set_digit_size(dssdev->panel.timings.x_res,
>>>    			dssdev->panel.timings.y_res);
>>>
>>> -	dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, 1);
>>> -
>>>    	hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 1);
>>>
>>> +	dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, 1);
>>> +
>>
>> What content would HDMI push out till the time DIGIT is enabled? It
>> might be interesting to put some milliseconds of delay here and see what
>> happens.
>
> I guess HDMI works independently of DISPC. So HDMI will output whatever
> is in the video port from DISPC to HDMI, regardless of what DISPC does.
> My guess is it's either random bits or, more probably, zeroes.

Okay. I thought HDMI block may probe the video port's DE line or 
something to check if it is pushing out valid content. However, with 
this patch, we are more aligned with what we do in power_off(), i.e 
first disable the manager and then disable HDMI.

Archit

>
> I think this way is the same as used for VENC: first we configure and
> enable VENC, then we enable DISPC digit output.
>
>   Tomi
>
>


^ permalink raw reply

* Re: [PATCHv2 09/15] OMAP: DSS2: HDMI: implement detect()
From: K, Mythri P @ 2011-09-12 13:36 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev, archit
In-Reply-To: <1315818818-18733-10-git-send-email-tomi.valkeinen@ti.com>

Hi Tomi,

On Mon, Sep 12, 2011 at 2:43 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> Implement detect() by checking the hot plug detect status.
>
> The implementation is not very good, as it always turns on the HDMI
> output to get the detection working. HDMI driver needs improvements so
> that we could enable only core parts of it.
>
> Cc: Mythri P K <mythripk@ti.com>
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> ---
>  drivers/video/omap2/dss/dss.h             |    1 +
>  drivers/video/omap2/dss/dss_features.c    |    1 +
>  drivers/video/omap2/dss/hdmi.c            |   17 +++++++++++++++++
>  drivers/video/omap2/dss/hdmi_panel.c      |   25 +++++++++++++++++++++++++
>  drivers/video/omap2/dss/ti_hdmi.h         |    3 +++
>  drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c |   12 ++++++++++++
>  6 files changed, 59 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
> index 2e7799c..f58c302 100644
> --- a/drivers/video/omap2/dss/dss.h
> +++ b/drivers/video/omap2/dss/dss.h
> @@ -495,6 +495,7 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev);
>  int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
>                                        struct omap_video_timings *timings);
>  int omapdss_hdmi_read_edid(u8 *buf, int len);
> +bool omapdss_hdmi_detect(void);
>  int hdmi_panel_init(void);
>  void hdmi_panel_exit(void);
>
> diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
> index 076f399..ab41665 100644
> --- a/drivers/video/omap2/dss/dss_features.c
> +++ b/drivers/video/omap2/dss/dss_features.c
> @@ -440,6 +440,7 @@ static const struct ti_hdmi_ip_ops omap4_hdmi_functions = {
>        .phy_enable             =       ti_hdmi_4xxx_phy_enable,
>        .phy_disable            =       ti_hdmi_4xxx_phy_disable,
>        .read_edid              =       ti_hdmi_4xxx_read_edid,
> +       .detect                 =       ti_hdmi_4xxx_detect,
>        .pll_enable             =       ti_hdmi_4xxx_pll_enable,
>        .pll_disable            =       ti_hdmi_4xxx_pll_disable,
>        .video_enable           =       ti_hdmi_4xxx_wp_video_start,
> diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
> index fb85ce5..7818670 100644
> --- a/drivers/video/omap2/dss/hdmi.c
> +++ b/drivers/video/omap2/dss/hdmi.c
> @@ -449,6 +449,23 @@ int omapdss_hdmi_read_edid(u8 *buf, int len)
>        return r;
>  }
>
> +bool omapdss_hdmi_detect(void)
> +{
> +       int r;
> +
> +       mutex_lock(&hdmi.lock);
> +
> +       r = hdmi_runtime_get();
> +       BUG_ON(r);
> +
> +       r = hdmi.ip_data.ops->detect(&hdmi.ip_data);
> +
> +       hdmi_runtime_put();
> +       mutex_unlock(&hdmi.lock);
> +
> +       return r = 1;
> +}
> +
>  int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
>  {
>        int r = 0;
> diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c
> index 71aa813..533d5dc 100644
> --- a/drivers/video/omap2/dss/hdmi_panel.c
> +++ b/drivers/video/omap2/dss/hdmi_panel.c
> @@ -25,6 +25,7 @@
>  #include <linux/mutex.h>
>  #include <linux/module.h>
>  #include <video/omapdss.h>
> +#include <linux/slab.h>
>
>  #include "dss.h"
>
> @@ -198,6 +199,29 @@ err:
>        return r;
>  }
>
> +static bool hdmi_detect(struct omap_dss_device *dssdev)
> +{
> +       int r;
> +
> +       mutex_lock(&hdmi.hdmi_lock);
> +
> +       if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
> +               r = omapdss_hdmi_display_enable(dssdev);
> +               if (r)
> +                       goto err;
> +       }
> +
> +       r = omapdss_hdmi_detect();
> +
> +       if (dssdev->state = OMAP_DSS_DISPLAY_DISABLED ||
> +                       dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED)
> +               omapdss_hdmi_display_disable(dssdev);
> +err:
> +       mutex_unlock(&hdmi.hdmi_lock);
> +
> +       return r;
> +}
> +
>  static struct omap_dss_driver hdmi_driver = {
>        .probe          = hdmi_panel_probe,
>        .remove         = hdmi_panel_remove,
> @@ -209,6 +233,7 @@ static struct omap_dss_driver hdmi_driver = {
>        .set_timings    = hdmi_set_timings,
>        .check_timings  = hdmi_check_timings,
>        .read_edid      = hdmi_read_edid,
> +       .detect         = hdmi_detect,
>        .driver                 = {
>                .name   = "hdmi_panel",
>                .owner  = THIS_MODULE,
> diff --git a/drivers/video/omap2/dss/ti_hdmi.h b/drivers/video/omap2/dss/ti_hdmi.h
> index 390cd85b..d48603c 100644
> --- a/drivers/video/omap2/dss/ti_hdmi.h
> +++ b/drivers/video/omap2/dss/ti_hdmi.h
> @@ -94,6 +94,8 @@ struct ti_hdmi_ip_ops {
>
>        int (*read_edid)(struct hdmi_ip_data *ip_data, u8 *edid, int len);
>
> +       bool (*detect)(struct hdmi_ip_data *ip_data);
> +
>        int (*pll_enable)(struct hdmi_ip_data *ip_data);
>
>        void (*pll_disable)(struct hdmi_ip_data *ip_data);
> @@ -114,6 +116,7 @@ struct hdmi_ip_data {
>  int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data);
>  void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data);
>  int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, u8 *edid, int len);
> +bool ti_hdmi_4xxx_detect(struct hdmi_ip_data *ip_data);
>  void ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start);
>  int ti_hdmi_4xxx_pll_enable(struct hdmi_ip_data *ip_data);
>  void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data);
> diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
> index e9885dc..da7fe50 100644
> --- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
> +++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
> @@ -416,6 +416,18 @@ int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data,
>        return l;
>  }
>
> +bool ti_hdmi_4xxx_detect(struct hdmi_ip_data *ip_data)
> +{
> +       int r;
> +
> +       void __iomem *base = hdmi_core_sys_base(ip_data);
> +
> +       /* HPD */
> +       r = REG_GET(base, HDMI_CORE_SYS_SYS_STAT, 1, 1);
> +
> +       return r = 1;
> +}
> +
For HPD the probe should also be on the core interrupt first , and the
detect should be dynamic, ie based on the cable connect and disconnect
event.So this approach for HPD is not really the way.
Also that should be based on the GPIO(63) , I am planning to push a
patch on that shortly.

>  static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
>                        struct hdmi_core_infoframe_avi *avi_cfg,
>                        struct hdmi_core_packet_enable_repeat *repeat_cfg)
> --
> 1.7.4.1
>
>
Thanks and regards,
Mythri.

^ 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