]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/gpu/drm/i915/intel_crt.c
drm/i915: Sync crt hotplug detection with intel video driver
[karo-tx-linux.git] / drivers / gpu / drm / i915 / intel_crt.c
index e58defa247d52f4d7f854c114332f447a7bdbfeb..2b6d44381c310874926eb9f2e8d55b5b6e91fad8 100644 (file)
@@ -146,20 +146,39 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       u32 temp;
-
-       unsigned long timeout = jiffies + msecs_to_jiffies(1000);
-
-       temp = I915_READ(PORT_HOTPLUG_EN);
-
-       I915_WRITE(PORT_HOTPLUG_EN,
-                  temp | CRT_HOTPLUG_FORCE_DETECT | (1 << 5));
+       u32 hotplug_en;
+       int i, tries = 0;
+       /*
+        * On 4 series desktop, CRT detect sequence need to be done twice
+        * to get a reliable result.
+        */
 
-       do {
-               if (!(I915_READ(PORT_HOTPLUG_EN) & CRT_HOTPLUG_FORCE_DETECT))
-                       break;
-               msleep(1);
-       } while (time_after(timeout, jiffies));
+       if (IS_G4X(dev) && !IS_GM45(dev))
+               tries = 2;
+       else
+               tries = 1;
+       hotplug_en = I915_READ(PORT_HOTPLUG_EN);
+       hotplug_en &= ~(CRT_HOTPLUG_MASK);
+       hotplug_en |= CRT_HOTPLUG_FORCE_DETECT;
+
+       if (IS_GM45(dev))
+               hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64;
+
+       hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50;
+
+       for (i = 0; i < tries ; i++) {
+               unsigned long timeout;
+               /* turn on the FORCE_DETECT */
+               I915_WRITE(PORT_HOTPLUG_EN, hotplug_en);
+               timeout = jiffies + msecs_to_jiffies(1000);
+               /* wait for FORCE_DETECT to go off */
+               do {
+                       if (!(I915_READ(PORT_HOTPLUG_EN) &
+                                       CRT_HOTPLUG_FORCE_DETECT))
+                               break;
+                       msleep(1);
+               } while (time_after(timeout, jiffies));
+       }
 
        if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) ==
            CRT_HOTPLUG_MONITOR_COLOR)