Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[pandora-kernel.git] / drivers / gpu / drm / i915 / intel_crt.c
index 6de97fc..590f81c 100644 (file)
@@ -46,7 +46,7 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
 
        temp = I915_READ(reg);
        temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
-       temp |= ADPA_DAC_ENABLE;
+       temp &= ~ADPA_DAC_ENABLE;
 
        switch(mode) {
        case DRM_MODE_DPMS_ON:
@@ -156,6 +156,9 @@ static bool intel_igdng_crt_detect_hotplug(struct drm_connector *connector)
 
        temp = adpa = I915_READ(PCH_ADPA);
 
+       adpa &= ~ADPA_DAC_ENABLE;
+       I915_WRITE(PCH_ADPA, adpa);
+
        adpa &= ~ADPA_CRT_HOTPLUG_MASK;
 
        adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 |
@@ -169,13 +172,14 @@ static bool intel_igdng_crt_detect_hotplug(struct drm_connector *connector)
        DRM_DEBUG("pch crt adpa 0x%x", adpa);
        I915_WRITE(PCH_ADPA, adpa);
 
-       /* This might not be needed as not specified in spec...*/
-       udelay(1000);
+       while ((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) != 0)
+               ;
 
        /* Check the status to see if both blue and green are on now */
        adpa = I915_READ(PCH_ADPA);
-       if ((adpa & ADPA_CRT_HOTPLUG_MONITOR_MASK) ==
-                       ADPA_CRT_HOTPLUG_MONITOR_COLOR)
+       adpa &= ADPA_CRT_HOTPLUG_MONITOR_MASK;
+       if ((adpa == ADPA_CRT_HOTPLUG_MONITOR_COLOR) ||
+               (adpa == ADPA_CRT_HOTPLUG_MONITOR_MONO))
                ret = true;
        else
                ret = false;
@@ -428,8 +432,34 @@ static void intel_crt_destroy(struct drm_connector *connector)
 
 static int intel_crt_get_modes(struct drm_connector *connector)
 {
+       int ret;
        struct intel_output *intel_output = to_intel_output(connector);
-       return intel_ddc_get_modes(intel_output);
+       struct i2c_adapter *ddcbus;
+       struct drm_device *dev = connector->dev;
+
+
+       ret = intel_ddc_get_modes(intel_output);
+       if (ret || !IS_G4X(dev))
+               goto end;
+
+       ddcbus = intel_output->ddc_bus;
+       /* Try to probe digital port for output in DVI-I -> VGA mode. */
+       intel_output->ddc_bus =
+               intel_i2c_create(connector->dev, GPIOD, "CRTDDC_D");
+
+       if (!intel_output->ddc_bus) {
+               intel_output->ddc_bus = ddcbus;
+               dev_printk(KERN_ERR, &connector->dev->pdev->dev,
+                          "DDC bus registration failed for CRTDDC_D.\n");
+               goto end;
+       }
+       /* Try to get modes by GPIOD port */
+       ret = intel_ddc_get_modes(intel_output);
+       intel_i2c_destroy(ddcbus);
+
+end:
+       return ret;
+
 }
 
 static int intel_crt_set_property(struct drm_connector *connector,
@@ -478,6 +508,7 @@ void intel_crt_init(struct drm_device *dev)
 {
        struct drm_connector *connector;
        struct intel_output *intel_output;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        u32 i2c_reg;
 
        intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
@@ -497,8 +528,12 @@ void intel_crt_init(struct drm_device *dev)
        /* Set up the DDC bus. */
        if (IS_IGDNG(dev))
                i2c_reg = PCH_GPIOA;
-       else
+       else {
                i2c_reg = GPIOA;
+               /* Use VBT information for CRT DDC if available */
+               if (dev_priv->crt_ddc_bus != -1)
+                       i2c_reg = dev_priv->crt_ddc_bus;
+       }
        intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A");
        if (!intel_output->ddc_bus) {
                dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
@@ -507,6 +542,10 @@ void intel_crt_init(struct drm_device *dev)
        }
 
        intel_output->type = INTEL_OUTPUT_ANALOG;
+       intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
+                                  (1 << INTEL_ANALOG_CLONE_BIT) |
+                                  (1 << INTEL_SDVO_LVDS_CLONE_BIT);
+       intel_output->crtc_mask = (1 << 0) | (1 << 1);
        connector->interlace_allowed = 0;
        connector->doublescan_allowed = 0;