[PATCH] OMAPDSS: HDMI: wait for RXDET before putting phy in TX_ON

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Mythri P K <mythripk@xxxxxx>

Currently TX_PHY is put to TX_ON(transmission state) on receiving HPD.
It just ensures that the TV is connected but does not guarantee
that TMDS data lines and clock lines are up and ready for transmission.
Which although is very rare scenario has a potential to  damage the HDMI
port.(A use case where TV is connected to board but it is in different
channel would still trigger a HPD but TMDS lines will be down).

Thus this patch adds a rxdet check on getting a HPD which ensures that
TMDS lines are UP before changing the PHY state from LDO_ON to TX_ON.

Signed-off-by: Mythri P K <mythripk@xxxxxx>
---
 drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c |   37 +++++++++++++++++++++++++++-
 drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h |    2 +
 2 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
index bb784d2..bc55528 100644
--- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
@@ -224,6 +224,30 @@ void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data)
 	hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_ALLOFF);
 }
 
+int hdmi_ti_4xxx_rxdet(struct hdmi_ip_data *ip_data)
+{
+	int loop = 0, tmds_data0, tmds_data1, tmds_data2, tmds_clk;
+
+	hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_WP_DEBUG_CFG, 4);
+
+	do {
+		tmds_data0 = hdmi_read_reg(hdmi_wp_base(ip_data),
+					HDMI_WP_WP_DEBUG_DATA);
+		tmds_data1 = hdmi_read_reg(hdmi_wp_base(ip_data),
+					HDMI_WP_WP_DEBUG_DATA);
+		tmds_data2 = hdmi_read_reg(hdmi_wp_base(ip_data),
+					HDMI_WP_WP_DEBUG_DATA);
+		tmds_clk = hdmi_read_reg(hdmi_wp_base(ip_data),
+					HDMI_WP_WP_DEBUG_DATA);
+		udelay(15);
+	} while ((tmds_data0 != tmds_data1 || tmds_data1 != tmds_data2
+			|| tmds_data1 != tmds_clk) && (loop < 500));
+
+	hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_WP_DEBUG_CFG, 0);
+
+	return ((loop == 500) ? -1 : (tmds_data0 & 1)) ;
+}
+
 static int hdmi_check_hpd_state(struct hdmi_ip_data *ip_data)
 {
 	unsigned long flags;
@@ -241,10 +265,19 @@ static int hdmi_check_hpd_state(struct hdmi_ip_data *ip_data)
 		return 0;
 	}
 
-	if (hpd)
+	if (hpd) {
+		/* before putting the phy in TX_ON,ensure that TMDS lanes
+		 * are pulled up .
+		 */
+		r = hdmi_ti_4xxx_rxdet(ip_data);
+		if (r <= 0) {
+			DSSERR("rxdet not set\n");
+			return r;
+		}
 		r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON);
-	else
+	} else {
 		r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON);
+	}
 
 	if (r) {
 		DSSERR("Failed to %s PHY TX power\n",
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h
index a14d1a0..efa6f29 100644
--- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h
@@ -47,6 +47,8 @@
 #define HDMI_WP_AUDIO_CFG2			0x84
 #define HDMI_WP_AUDIO_CTRL			0x88
 #define HDMI_WP_AUDIO_DATA			0x8C
+#define HDMI_WP_WP_DEBUG_CFG			0x90
+#define HDMI_WP_WP_DEBUG_DATA			0x94
 
 /* HDMI IP Core System */
 
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux