Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1203304

[PATCH 11/12] drm: bridge/dw_hdmi: add connector mode forcing

From Russell King <rmk+kernel@arm.linux.org.uk>
Newsgroups linux.kernel
Subject [PATCH 11/12] drm: bridge/dw_hdmi: add connector mode forcing
Date 2015-08-08 18:10 +0200
Message-ID <pVeR5-3EB-35@gated-at.bofh.it> (permalink)
References <pVeR3-3EB-3@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


When connected to HDMI sources, some DVI monitors de-assert their HPD
signal and TDMS loads for one seconds every four seconds when there is
no signal present on the connection.

Unfortunately, this behaviour is indistinguishable from a proper HDMI
setup with an AV receiver in the path to the display: the HDMI spec
requires us to detect HPD deassertions as short as 100ms, which indicate
that the EDID has changed.

Since it is possible to connect a DVI monitor to an AV receiver and then
to a HDMI source, merely working around this by detecting the lack of
HDMI vendor block in the EDID is insufficient - the AV receiver is at
liberty to modify the EDID as it sees fit, and it will place its own
parameters into the EDID including the HDMI vendor block.

DRM has support for forcing the state of a connector, which we should
implement to allow us to work around these broken DVI monitors - we can
tell DRM to force the connection state to indicate that there is always
a device connected to work around this problem.  Although this requires
manual configuration, it is better than nothing at all.

When a forced connection state has been set, there is no point handling
our RXSENSE interrupts, so disable them in this circumstance.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/gpu/drm/bridge/dw_hdmi.c | 51 ++++++++++++++++++++++++++++++++++++----
 1 file changed, 47 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 0ee188930d26..2d1c7e4ec086 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -126,7 +126,9 @@ struct dw_hdmi {
 	bool sink_has_audio;
 
 	struct mutex mutex;		/* for state below and previous_mode */
+	enum drm_connector_force force;	/* mutex-protected force state */
 	bool disabled;			/* DRM has disabled our bridge */
+	bool bridge_is_on;		/* indicates the bridge is on */
 
 	spinlock_t audio_lock;
 	struct mutex audio_mutex;
@@ -1378,12 +1380,36 @@ static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi)
 
 static void dw_hdmi_poweron(struct dw_hdmi *hdmi)
 {
+	hdmi->bridge_is_on = true;
 	dw_hdmi_setup(hdmi, &hdmi->previous_mode);
 }
 
 static void dw_hdmi_poweroff(struct dw_hdmi *hdmi)
 {
 	dw_hdmi_phy_disable(hdmi);
+	hdmi->bridge_is_on = false;
+}
+
+static void dw_hdmi_update_power(struct dw_hdmi *hdmi)
+{
+	int force = hdmi->force;
+
+	if (hdmi->disabled) {
+		force = DRM_FORCE_OFF;
+	} else if (force == DRM_FORCE_UNSPECIFIED) {
+		if (hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD)
+			force = DRM_FORCE_ON;
+		else
+			force = DRM_FORCE_OFF;
+	}
+
+	if (force == DRM_FORCE_OFF) {
+		if (hdmi->bridge_is_on)
+			dw_hdmi_poweroff(hdmi);
+	} else {
+		if (!hdmi->bridge_is_on)
+			dw_hdmi_poweron(hdmi);
+	}
 }
 
 static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge,
@@ -1413,7 +1439,7 @@ static void dw_hdmi_bridge_disable(struct drm_bridge *bridge)
 
 	mutex_lock(&hdmi->mutex);
 	hdmi->disabled = true;
-	dw_hdmi_poweroff(hdmi);
+	dw_hdmi_update_power(hdmi);
 	mutex_unlock(&hdmi->mutex);
 }
 
@@ -1422,8 +1448,8 @@ static void dw_hdmi_bridge_enable(struct drm_bridge *bridge)
 	struct dw_hdmi *hdmi = bridge->driver_private;
 
 	mutex_lock(&hdmi->mutex);
-	dw_hdmi_poweron(hdmi);
 	hdmi->disabled = false;
+	dw_hdmi_update_power(hdmi);
 	mutex_unlock(&hdmi->mutex);
 }
 
@@ -1438,6 +1464,11 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
 	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
 					     connector);
 
+	mutex_lock(&hdmi->mutex);
+	hdmi->force = DRM_FORCE_UNSPECIFIED;
+	dw_hdmi_update_power(hdmi);
+	mutex_unlock(&hdmi->mutex);
+
 	return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
 		connector_status_connected : connector_status_disconnected;
 }
@@ -1502,11 +1533,23 @@ static void dw_hdmi_connector_destroy(struct drm_connector *connector)
 	drm_connector_cleanup(connector);
 }
 
+static void dw_hdmi_connector_force(struct drm_connector *connector)
+{
+	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
+					     connector);
+
+	mutex_lock(&hdmi->mutex);
+	hdmi->force = connector->force;
+	dw_hdmi_update_power(hdmi);
+	mutex_unlock(&hdmi->mutex);
+}
+
 static struct drm_connector_funcs dw_hdmi_connector_funcs = {
 	.dpms = drm_helper_connector_dpms,
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.detect = dw_hdmi_connector_detect,
 	.destroy = dw_hdmi_connector_destroy,
+	.force = dw_hdmi_connector_force,
 };
 
 static struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = {
@@ -1552,12 +1595,12 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
 		if (phy_int_pol & HDMI_PHY_HPD) {
 			dev_dbg(hdmi->dev, "EVENT=plugin\n");
 
-			if (!hdmi->disabled)
+			if (!hdmi->disabled && !hdmi->force)
 				dw_hdmi_poweron(hdmi);
 		} else {
 			dev_dbg(hdmi->dev, "EVENT=plugout\n");
 
-			if (!hdmi->disabled)
+			if (!hdmi->disabled && !hdmi->force)
 				dw_hdmi_poweroff(hdmi);
 		}
 		mutex_unlock(&hdmi->mutex);
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Back to linux.kernel | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

[PATCH 00/12] dw-hdmi development Russell King - ARM Linux <linux@arm.linux.org.uk> - 2015-08-08 18:10 +0200
  [PATCH 05/12] drm: bridge/dw_hdmi: add support for interlaced video  modes Russell King <rmk+kernel@arm.linux.org.uk> - 2015-08-08 18:10 +0200
  [PATCH 12/12] drm: bridge/dw_hdmi: improve HDMI enable/disable  handling Russell King <rmk+kernel@arm.linux.org.uk> - 2015-08-08 18:10 +0200
  Re: [PATCH 0/9] dw-hdmi audio support Russell King - ARM Linux <linux@arm.linux.org.uk> - 2015-08-08 18:10 +0200
    [PATCH 2/9] drm: bridge/dw_hdmi-ahb-audio: parse ELD from HDMI driver Russell King <rmk+kernel@arm.linux.org.uk> - 2015-08-08 18:20 +0200
    [PATCH 6/9] drm: bridge/dw_hdmi: adjust pixel clock values in N  calculation Russell King <rmk+kernel@arm.linux.org.uk> - 2015-08-08 18:20 +0200
    [PATCH 5/9] drm: bridge/dw_hdmi: avoid being recursive in N  calculation Russell King <rmk+kernel@arm.linux.org.uk> - 2015-08-08 18:20 +0200
    [PATCH 4/9] drm: bridge/dw_hdmi-ahb-audio: allow larger buffer sizes Russell King <rmk+kernel@arm.linux.org.uk> - 2015-08-08 18:20 +0200
    [PATCH 8/9] drm: bridge/dw_hdmi: replace CTS calculation for the ACR Russell King <rmk+kernel@arm.linux.org.uk> - 2015-08-08 18:20 +0200
    [PATCH 7/9] drm: bridge/dw_hdmi: remove ratio support from ACR code Russell King <rmk+kernel@arm.linux.org.uk> - 2015-08-08 18:20 +0200
    [PATCH 9/9] drm: bridge/dw_hdmi-i2s-audio: add audio driver Russell King <rmk+kernel@arm.linux.org.uk> - 2015-08-08 18:20 +0200
      Re: [PATCH 9/9] drm: bridge/dw_hdmi-i2s-audio: add audio driver Russell King - ARM Linux <linux@arm.linux.org.uk> - 2015-08-10 17:50 +0200
        Re: [PATCH 9/9] drm: bridge/dw_hdmi-i2s-audio: add audio driver Yakir Yang <ykk@rock-chips.com> - 2015-08-10 18:30 +0200
    [PATCH 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver Russell King <rmk+kernel@arm.linux.org.uk> - 2015-08-08 18:20 +0200
      Re: [PATCH 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver Takashi Iwai <tiwai@suse.de> - 2015-08-10 12:10 +0200
        Re: [PATCH 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver Russell King - ARM Linux <linux@arm.linux.org.uk> - 2015-08-10 12:40 +0200
          Re: [PATCH 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver Takashi Iwai <tiwai@suse.de> - 2015-08-10 14:30 +0200
            Re: [PATCH 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver Russell King - ARM Linux <linux@arm.linux.org.uk> - 2015-08-10 19:00 +0200
              Re: [PATCH 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver Mark Brown <broonie@kernel.org> - 2015-08-10 20:20 +0200
        Re: [PATCH v2 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver         David Airlie <airlied@linux.ie>, Sascha Hauer <s.hauer@pengutronix.de>,         linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Jaroslav         Kysela <perex@perex.cz>, linux-rockchip@lists.infradead.org, Mark Brown         <broonie@kernel.org>, Philipp Zabel <p.zabel@pengutronix.de>, Yakir         Yang <ykk@rock-chips.com>, Andy Yan <andy.yan@rock-chips.com>, Jon         Nettleton <jon.nettleton@gmail.com>,         linux-arm-kernel@lists.infradead.org Russell King <rmk+kernel@arm.linux.org.uk> - 2015-08-14 16:00 +0200
        Re: [PATCH v2 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver Russell King <rmk+kernel@arm.linux.org.uk> - 2015-08-14 16:10 +0200
          Re: [alsa-devel] [PATCH v2 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver Takashi Iwai <tiwai@suse.de> - 2015-08-14 16:40 +0200
    [PATCH 3/9] drm: bridge/dw_hdmi-ahb-audio: basic support for  multi-channel PCM audio Russell King <rmk+kernel@arm.linux.org.uk> - 2015-08-08 18:20 +0200
  [PATCH 08/12] drm: bridge/dw_hdmi: avoid enabling interface in  mode_set Russell King <rmk+kernel@arm.linux.org.uk> - 2015-08-08 18:10 +0200
  [PATCH 04/12] gpu: imx: fix support for interlaced modes Russell King <rmk+kernel@arm.linux.org.uk> - 2015-08-08 18:10 +0200
  [PATCH 09/12] drm: bridge/dw_hdmi: rename dw_hdmi_phy_enable_power() Russell King <rmk+kernel@arm.linux.org.uk> - 2015-08-08 18:10 +0200
  [PATCH 03/12] gpu: imx: simplify sync polarity setting Russell King <rmk+kernel@arm.linux.org.uk> - 2015-08-08 18:10 +0200
  [PATCH 01/12] drm: bridge/dw_hdmi: remove pixel repetition setting  for all VICs Russell King <rmk+kernel@arm.linux.org.uk> - 2015-08-08 18:10 +0200
  [PATCH 02/12] drm: bridge/dw_hdmi: don't support any pixel doubled  modes Russell King <rmk+kernel@arm.linux.org.uk> - 2015-08-08 18:10 +0200
  [PATCH 06/12] drm: bridge/dw_hdmi: clean up HDMI vs DVI mode handling Russell King <rmk+kernel@arm.linux.org.uk> - 2015-08-08 18:10 +0200
  [PATCH 11/12] drm: bridge/dw_hdmi: add connector mode forcing Russell King <rmk+kernel@arm.linux.org.uk> - 2015-08-08 18:10 +0200
  [PATCH 10/12] drm: bridge/dw_hdmi: fix phy enable/disable handling Russell King <rmk+kernel@arm.linux.org.uk> - 2015-08-08 18:20 +0200
  Re: [PATCH 00/12] dw-hdmi development Thierry Reding <thierry.reding@gmail.com> - 2015-08-10 14:30 +0200
    Re: [PATCH 00/12] dw-hdmi development Russell King - ARM Linux <linux@arm.linux.org.uk> - 2015-08-18 12:40 +0200

csiph-web