drm/i915: Sync crt hotplug detection with intel video driver
authorZhao Yakui <yakui.zhao@intel.com>
Tue, 3 Mar 2009 10:07:52 +0000 (18:07 +0800)
committerEric Anholt <eric@anholt.net>
Fri, 27 Mar 2009 22:12:11 +0000 (15:12 -0700)
This covers:
Use long crt hotplug activation time on GM45.

Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_crt.c

index 6d56777..05b1894 100644 (file)
 #define   TV_HOTPLUG_INT_EN                    (1 << 18)
 #define   CRT_HOTPLUG_INT_EN                   (1 << 9)
 #define   CRT_HOTPLUG_FORCE_DETECT             (1 << 3)
+#define CRT_HOTPLUG_ACTIVATION_PERIOD_32       (0 << 8)
+/* must use period 64 on GM45 according to docs */
+#define CRT_HOTPLUG_ACTIVATION_PERIOD_64       (1 << 8)
+#define CRT_HOTPLUG_DAC_ON_TIME_2M             (0 << 7)
+#define CRT_HOTPLUG_DAC_ON_TIME_4M             (1 << 7)
+#define CRT_HOTPLUG_VOLTAGE_COMPARE_40         (0 << 5)
+#define CRT_HOTPLUG_VOLTAGE_COMPARE_50         (1 << 5)
+#define CRT_HOTPLUG_VOLTAGE_COMPARE_60         (2 << 5)
+#define CRT_HOTPLUG_VOLTAGE_COMPARE_70         (3 << 5)
+#define CRT_HOTPLUG_VOLTAGE_COMPARE_MASK       (3 << 5)
+#define CRT_HOTPLUG_DETECT_DELAY_1G            (0 << 4)
+#define CRT_HOTPLUG_DETECT_DELAY_2G            (1 << 4)
+#define CRT_HOTPLUG_DETECT_VOLTAGE_325MV       (0 << 2)
+#define CRT_HOTPLUG_DETECT_VOLTAGE_475MV       (1 << 2)
+#define CRT_HOTPLUG_MASK                       (0x3fc) /* Bits 9-2 */
+
 
 #define PORT_HOTPLUG_STAT      0x61114
 #define   HDMIB_HOTPLUG_INT_STATUS             (1 << 29)
index e58defa..2b6d443 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)