Merge branch 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel...
authorDave Airlie <airlied@redhat.com>
Sun, 21 Oct 2012 23:55:29 +0000 (09:55 +1000)
committerDave Airlie <airlied@redhat.com>
Sun, 21 Oct 2012 23:55:48 +0000 (09:55 +1000)
Daniel writes:
The big thing is the disabling of the hsw support by default, cc: stable.
We've aimed for basic hsw support in 3.6, but due to a few bad
happenstances we've screwed up and only 3.8 will have better modeset
support than vesa. To avoid yet another round of fallout from such a
gaffle on for the next platform we've added a module option to disable
early hw support by default. That should also give us more flexibility in
bring-up.

 Otherwise just small fixes:
 - 3 fixes from Egbert for sdvo corner cases
 - invert-brightness quirk entry from Egbert
 - revert a dp link training change, it regresses some setups
 - and shut up a spurious WARN in our gem fault handler.
 - regression fix for an oops on bit17 swizzling machines, introduce in 3.7
 - another no-lvds quirk

* 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel:
  drm/i915: Initialize obj->pages before use by i915_gem_object_do_bit17_swizzle()
  drm/i915: Add no-lvds quirk for Supermicro X7SPA-H
  drm/i915: Insert i915_preliminary_hw_support variable.
  drm/i915: shut up spurious WARN in the gtt fault handler
  Revert "drm/i915: Try harder to complete DP training pattern 1"
  DRM/i915: Restore sdvo_flags after dtd->mode->dtd Roundrtrip.
  DRM/i915: Don't clone SDVO LVDS with analog.
  DRM/i915: Add QUIRK_INVERT_BRIGHTNESS for NCR machines.
  DRM/i915: Don't delete DPLL Multiplier during DAC init.

drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/intel_crt.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_sdvo.c

index aac4e5e1a5b9b3533f36f801be7c553c2e60c8a1..6770ee6084b478475c3dde3a9bec72fff1e11a53 100644 (file)
@@ -118,6 +118,13 @@ module_param_named(i915_enable_ppgtt, i915_enable_ppgtt, int, 0600);
 MODULE_PARM_DESC(i915_enable_ppgtt,
                "Enable PPGTT (default: true)");
 
+unsigned int i915_preliminary_hw_support __read_mostly = 0;
+module_param_named(preliminary_hw_support, i915_preliminary_hw_support, int, 0600);
+MODULE_PARM_DESC(preliminary_hw_support,
+               "Enable preliminary hardware support. "
+               "Enable Haswell and ValleyView Support. "
+               "(default: false)");
+
 static struct drm_driver driver;
 extern int intel_agp_enabled;
 
@@ -826,6 +833,12 @@ i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        struct intel_device_info *intel_info =
                (struct intel_device_info *) ent->driver_data;
 
+       if (intel_info->is_haswell || intel_info->is_valleyview)
+               if(!i915_preliminary_hw_support) {
+                       DRM_ERROR("Preliminary hardware support disabled\n");
+                       return -ENODEV;
+               }
+
        /* Only bind to function 0 of the device. Early generations
         * used function 1 as a placeholder for multi-head. This causes
         * us confusion instead, especially on the systems where both
index b84f7861e4388cb3ccd8baa86ec3d994e4e52ceb..f511fa2f41687718494f2f1d9e2afb0c24f1fb70 100644 (file)
@@ -1217,6 +1217,7 @@ extern int i915_enable_rc6 __read_mostly;
 extern int i915_enable_fbc __read_mostly;
 extern bool i915_enable_hangcheck __read_mostly;
 extern int i915_enable_ppgtt __read_mostly;
+extern unsigned int i915_preliminary_hw_support __read_mostly;
 
 extern int i915_suspend(struct drm_device *dev, pm_message_t state);
 extern int i915_resume(struct drm_device *dev);
index d33d02d13c9678a7dd64b1fb4c9e9c5f9682d223..107f09befe929540e9ad801ff2bbdfe97a6b651d 100644 (file)
@@ -1407,8 +1407,10 @@ out:
                return VM_FAULT_NOPAGE;
        case -ENOMEM:
                return VM_FAULT_OOM;
+       case -ENOSPC:
+               return VM_FAULT_SIGBUS;
        default:
-               WARN_ON_ONCE(ret);
+               WARN_ONCE(ret, "unhandled error in i915_gem_fault: %i\n", ret);
                return VM_FAULT_SIGBUS;
        }
 }
@@ -1822,10 +1824,11 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
                sg_set_page(sg, page, PAGE_SIZE, 0);
        }
 
+       obj->pages = st;
+
        if (i915_gem_object_needs_bit17_swizzle(obj))
                i915_gem_object_do_bit_17_swizzle(obj);
 
-       obj->pages = st;
        return 0;
 
 err_pages:
index 893f30164b7ec70a5cd2308db6db1e3e55222d6f..f78061af70459d6f4e39c25e79d8ff722ccb7aa2 100644 (file)
@@ -219,20 +219,7 @@ static void intel_crt_mode_set(struct drm_encoder *encoder,
                intel_encoder_to_crt(to_intel_encoder(encoder));
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        struct drm_i915_private *dev_priv = dev->dev_private;
-       int dpll_md_reg;
-       u32 adpa, dpll_md;
-
-       dpll_md_reg = DPLL_MD(intel_crtc->pipe);
-
-       /*
-        * Disable separate mode multiplier used when cloning SDVO to CRT
-        * XXX this needs to be adjusted when we really are cloning
-        */
-       if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) {
-               dpll_md = I915_READ(dpll_md_reg);
-               I915_WRITE(dpll_md_reg,
-                          dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK);
-       }
+       u32 adpa;
 
        adpa = ADPA_HOTPLUG_BITS;
        if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
index 682bd3729baf62369fc66d23434f058a643ffc78..461a637f1ef7d96a21ced8cd31ffd1536a7257a2 100644 (file)
@@ -7892,6 +7892,34 @@ struct intel_quirk {
        void (*hook)(struct drm_device *dev);
 };
 
+/* For systems that don't have a meaningful PCI subdevice/subvendor ID */
+struct intel_dmi_quirk {
+       void (*hook)(struct drm_device *dev);
+       const struct dmi_system_id (*dmi_id_list)[];
+};
+
+static int intel_dmi_reverse_brightness(const struct dmi_system_id *id)
+{
+       DRM_INFO("Backlight polarity reversed on %s\n", id->ident);
+       return 1;
+}
+
+static const struct intel_dmi_quirk intel_dmi_quirks[] = {
+       {
+               .dmi_id_list = &(const struct dmi_system_id[]) {
+                       {
+                               .callback = intel_dmi_reverse_brightness,
+                               .ident = "NCR Corporation",
+                               .matches = {DMI_MATCH(DMI_SYS_VENDOR, "NCR Corporation"),
+                                           DMI_MATCH(DMI_PRODUCT_NAME, ""),
+                               },
+                       },
+                       { }  /* terminating entry */
+               },
+               .hook = quirk_invert_brightness,
+       },
+};
+
 static struct intel_quirk intel_quirks[] = {
        /* HP Mini needs pipe A force quirk (LP: #322104) */
        { 0x27ae, 0x103c, 0x361a, quirk_pipea_force },
@@ -7931,6 +7959,10 @@ static void intel_init_quirks(struct drm_device *dev)
                     q->subsystem_device == PCI_ANY_ID))
                        q->hook(dev);
        }
+       for (i = 0; i < ARRAY_SIZE(intel_dmi_quirks); i++) {
+               if (dmi_check_system(*intel_dmi_quirks[i].dmi_id_list) != 0)
+                       intel_dmi_quirks[i].hook(dev);
+       }
 }
 
 /* Disable the VGA plane that we never use */
index 1b727a5c9ee5680364343be93e15203df42e2369..368ed8ef1600233b6df90f32a591b46ea8fbdf88 100644 (file)
@@ -1797,7 +1797,8 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
                        if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
                                break;
                if (i == intel_dp->lane_count && voltage_tries == 5) {
-                       if (++loop_tries == 5) {
+                       ++loop_tries;
+                       if (loop_tries == 5) {
                                DRM_DEBUG_KMS("too many full retries, give up\n");
                                break;
                        }
@@ -1807,11 +1808,15 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
                }
 
                /* Check to see if we've tried the same voltage 5 times */
-               if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) != voltage) {
-                       voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
-                       voltage_tries = 0;
-               } else
+               if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
                        ++voltage_tries;
+                       if (voltage_tries == 5) {
+                               DRM_DEBUG_KMS("too many voltage retries, give up\n");
+                               break;
+                       }
+               } else
+                       voltage_tries = 0;
+               voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
 
                /* Compute new intel_dp->train_set as requested by target */
                intel_get_adjust_train(intel_dp, link_status);
index e3166df55daad03f4f5c144a5c0558aaa017fec6..edba93b3474b9540a5608f6acbd9eb75f7e53a33 100644 (file)
@@ -777,6 +777,14 @@ static const struct dmi_system_id intel_no_lvds[] = {
                        DMI_MATCH(DMI_BOARD_NAME, "D525TUD"),
                },
        },
+       {
+               .callback = intel_no_lvds_dmi_callback,
+               .ident = "Supermicro X7SPA-H",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "X7SPA-H"),
+               },
+       },
 
        { }     /* terminating entry */
 };
index 0007a4d9bf6e5248effc509fd25f442b6d4e3164..c01d97db0061d19be180f6dbcf9cecffd505aeb0 100644 (file)
@@ -139,6 +139,11 @@ struct intel_sdvo {
 
        /* DDC bus used by this SDVO encoder */
        uint8_t ddc_bus;
+
+       /*
+        * the sdvo flag gets lost in round trip: dtd->adjusted_mode->dtd
+        */
+       uint8_t dtd_sdvo_flags;
 };
 
 struct intel_sdvo_connector {
@@ -984,6 +989,7 @@ intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo,
                return false;
 
        intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
+       intel_sdvo->dtd_sdvo_flags = input_dtd.part2.sdvo_flags;
 
        return true;
 }
@@ -1092,6 +1098,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
         * adjusted_mode.
         */
        intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);
+       if (intel_sdvo->is_tv || intel_sdvo->is_lvds)
+               input_dtd.part2.sdvo_flags = intel_sdvo->dtd_sdvo_flags;
        if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd))
                DRM_INFO("Setting input timings on %s failed\n",
                         SDVO_NAME(intel_sdvo));
@@ -2277,10 +2285,8 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
                intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1;
        }
 
-       /* SDVO LVDS is cloneable because the SDVO encoder does the upscaling,
-        * as opposed to native LVDS, where we upscale with the panel-fitter
-        * (and hence only the native LVDS resolution could be cloned). */
-       intel_sdvo->base.cloneable = true;
+       /* SDVO LVDS is not cloneable because the input mode gets adjusted by the encoder */
+       intel_sdvo->base.cloneable = false;
 
        intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
        if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector))