]> xenbits.xensource.com Git - people/aperard/linux-chromebook.git/commitdiff
Reiplace HDMI unplug polling with HPD line reading.
authorStuart Abercrombie <sabercrombie@chromium.org>
Thu, 17 Jan 2013 00:52:17 +0000 (16:52 -0800)
committerChromeBot <chrome-bot@google.com>
Thu, 17 Jan 2013 02:31:52 +0000 (18:31 -0800)
It looked as if this didn't work at the HW level, but it actually does.
Polling cost us about 100mW if an HDMI monitor was attached.
This also responds more quickly to unplugging.

Based on upstream change:
http://lists.freedesktop.org/archives/intel-gfx/2012-December/023314.html

BUG=chromium-os:37674
TEST=HDMI hotplug works and responds immediately
Change-Id: I9e88671b1ac0e6204feda2666608f30427c8bb79
Reviewed-on: https://gerrit.chromium.org/gerrit/41474
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
Tested-by: Stuart Abercrombie <sabercrombie@chromium.org>
Commit-Queue: Stuart Abercrombie <sabercrombie@chromium.org>

drivers/gpu/drm/drm_crtc_helper.c
drivers/gpu/drm/i915/intel_hdmi.c
include/drm/drm_crtc.h

index 678f1b8ba9683675a7a1a16129e0b4f499021104..ec8a192c85ffa37a8f6b3a81f75afcbfa8fc52df 100644 (file)
@@ -937,13 +937,9 @@ static void output_poll_execute(struct work_struct *work)
                   TV out for instance */
                if (!connector->polled)
                        continue;
-
-               if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT)) {
-                       if (connector->polled & DRM_CONNECTOR_POLL_DISCONNECT_ONLY)
-                               repoll = (connector->status == connector_status_connected);
-                       else
-                               repoll = true;
-               }
+               else if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT |
+                        DRM_CONNECTOR_POLL_DISCONNECT))
+                       repoll = true;
 
                old_status = connector->status;
                /* if we are connected and don't want to poll for disconnect
index 6f943d52ef0ae97f2f6f1d96b30b5dd0d3fc596c..e2bd4891d79aadb3db20882d5fc3b0e1c64a3330 100644 (file)
@@ -336,6 +336,41 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
        return true;
 }
 
+/*
+ * intel_hdmi_hpd- is the specified port connected?
+ * @dev_priv: i915 private structure
+ * @intel_hdmi: the HDMI port to test
+ *
+ * Returns true if @intel_hdmi is connected, false otherwise.
+ */
+static bool intel_hdmi_hpd(struct drm_i915_private *dev_priv,
+                                          struct intel_hdmi *intel_hdmi)
+{
+       u32 bit;
+
+       /* XXX: IBX has different SDEISR bits */
+       if (HAS_PCH_IBX(dev_priv->dev))
+               return true;
+
+       switch (intel_hdmi->sdvox_reg) {
+       case HDMIB:
+       case SDVOB:
+               bit = SDE_PORTB_HOTPLUG_CPT;
+               break;
+       case HDMIC:
+       case SDVOC:
+               bit = SDE_PORTC_HOTPLUG_CPT;
+               break;
+       case HDMID:
+               bit = SDE_PORTD_HOTPLUG_CPT;
+               break;
+       default:
+               return true;
+       }
+
+       return I915_READ(SDEISR) & bit;
+}
+
 static enum drm_connector_status
 intel_hdmi_detect(struct drm_connector *connector, bool force)
 {
@@ -346,6 +381,11 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
 
        intel_hdmi->has_hdmi_sink = false;
        intel_hdmi->has_audio = false;
+
+       if (HAS_PCH_SPLIT(connector->dev) &&
+           !intel_hdmi_hpd(dev_priv, intel_hdmi))
+               return status;
+
        edid = drm_get_edid(connector,
                            intel_gmbus_get_adapter(dev_priv,
                                                    intel_hdmi->ddc_bus));
@@ -532,7 +572,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
 
        intel_encoder->type = INTEL_OUTPUT_HDMI;
 
-       connector->polled = DRM_CONNECTOR_POLL_DISCONNECT | DRM_CONNECTOR_POLL_DISCONNECT_ONLY;
+       connector->polled = DRM_CONNECTOR_POLL_HPD;
        connector->interlace_allowed = 1;
        connector->doublescan_allowed = 0;
        intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
index 4abc1985afedd5bd85b3b69379643d4f78cc07a6..f1a0764b6c547083c5a373c20d0b52890c645182 100644 (file)
@@ -499,8 +499,6 @@ enum drm_connector_force {
 /* can cleanly poll for disconnections without flickering the screen */
 /* DACs should rarely do this without a lot of testing */
 #define DRM_CONNECTOR_POLL_DISCONNECT (1 << 2)
-/* Only poll for disconnections. */
-#define DRM_CONNECTOR_POLL_DISCONNECT_ONLY (1 << 3)
 
 #define MAX_ELD_BYTES  128