]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
drm/i915: Sync crt hotplug detection with intel video driver
authorZhao Yakui <yakui.zhao@intel.com>
Tue, 7 Apr 2009 02:40:19 +0000 (19:40 -0700)
committerChris Wright <chrisw@sous-sol.org>
Mon, 27 Apr 2009 17:36:53 +0000 (10:36 -0700)
upstream commit: 771cb081354161eea21534ba58e5cc1a2db94a25

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>
Signed-off-by: Chris Wright <chrisw@sous-sol.org>
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_crt.c

index 90600d89941375c7b3257ce8769621942366d670..cc2938d94a97c1a90d5a18156874a1e257e588ab 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 dcaed3466e835efb1be64b6ece3189e9c38f508c..61c108eef13ff2cf2fd8a23b3b5c3896642aa3f2 100644 (file)
@@ -133,20 +133,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)