Merge branch 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel...
authorDave Airlie <airlied@redhat.com>
Fri, 24 May 2013 00:15:12 +0000 (10:15 +1000)
committerDave Airlie <airlied@redhat.com>
Fri, 24 May 2013 00:15:12 +0000 (10:15 +1000)
Daniel writes:
A few fixes, nothing shocking:
- More Haswell pci ids. Includes a pile of marketing spare ids (which
  despite the spare moniker show up all over the place).
- Fix a regression in handling modeset failures, resulting in black
  screens on 3 pipe setups when we've run out of pch plls (Chris).
- Fix up the setcrtc semantics to unconditionally enable the outputs.
  Juding from git digging that has (kinda) always been the case and neatly
  fixes a few long-standing (i.e. forever) bug reports (Imre).
- jiffies_timeout + 1 patches from Imre. They partially fix spurious
  wait_event failures in the interrupt-driven dp aux/i2c code. The other
  part is a core patch for the wait_event macros going in through -mm. A
  few patches more than strictly required since Imre is pushing for a
  general solution in 3.11.

* 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel:
  drm/i915: avoid premature DP AUX timeouts
  drm/i915: avoid premature timeouts in __wait_seqno()
  drm/i915: use msecs_to_jiffies_timeout instead of open coding the same
  drm/i915: add msecs_to_jiffies_timeout to guarantee minimum duration
  drm/i915: force full modeset if the connector is in DPMS OFF mode
  drm/i915: Propagate errors back from fb set-base
  drm/i915: Adding more reserved PCI IDs for Haswell.

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_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_i2c.c

index 9ebe895..a2e4953 100644 (file)
@@ -364,40 +364,64 @@ static const struct pci_device_id pciidlist[] = {         /* aka */
        INTEL_VGA_DEVICE(0x016a, &intel_ivybridge_d_info), /* GT2 server */
        INTEL_VGA_DEVICE(0x0402, &intel_haswell_d_info), /* GT1 desktop */
        INTEL_VGA_DEVICE(0x0412, &intel_haswell_d_info), /* GT2 desktop */
-       INTEL_VGA_DEVICE(0x0422, &intel_haswell_d_info), /* GT2 desktop */
+       INTEL_VGA_DEVICE(0x0422, &intel_haswell_d_info), /* GT3 desktop */
        INTEL_VGA_DEVICE(0x040a, &intel_haswell_d_info), /* GT1 server */
        INTEL_VGA_DEVICE(0x041a, &intel_haswell_d_info), /* GT2 server */
-       INTEL_VGA_DEVICE(0x042a, &intel_haswell_d_info), /* GT2 server */
+       INTEL_VGA_DEVICE(0x042a, &intel_haswell_d_info), /* GT3 server */
        INTEL_VGA_DEVICE(0x0406, &intel_haswell_m_info), /* GT1 mobile */
        INTEL_VGA_DEVICE(0x0416, &intel_haswell_m_info), /* GT2 mobile */
        INTEL_VGA_DEVICE(0x0426, &intel_haswell_m_info), /* GT2 mobile */
+       INTEL_VGA_DEVICE(0x040B, &intel_haswell_d_info), /* GT1 reserved */
+       INTEL_VGA_DEVICE(0x041B, &intel_haswell_d_info), /* GT2 reserved */
+       INTEL_VGA_DEVICE(0x042B, &intel_haswell_d_info), /* GT3 reserved */
+       INTEL_VGA_DEVICE(0x040E, &intel_haswell_d_info), /* GT1 reserved */
+       INTEL_VGA_DEVICE(0x041E, &intel_haswell_d_info), /* GT2 reserved */
+       INTEL_VGA_DEVICE(0x042E, &intel_haswell_d_info), /* GT3 reserved */
        INTEL_VGA_DEVICE(0x0C02, &intel_haswell_d_info), /* SDV GT1 desktop */
        INTEL_VGA_DEVICE(0x0C12, &intel_haswell_d_info), /* SDV GT2 desktop */
-       INTEL_VGA_DEVICE(0x0C22, &intel_haswell_d_info), /* SDV GT2 desktop */
+       INTEL_VGA_DEVICE(0x0C22, &intel_haswell_d_info), /* SDV GT3 desktop */
        INTEL_VGA_DEVICE(0x0C0A, &intel_haswell_d_info), /* SDV GT1 server */
        INTEL_VGA_DEVICE(0x0C1A, &intel_haswell_d_info), /* SDV GT2 server */
-       INTEL_VGA_DEVICE(0x0C2A, &intel_haswell_d_info), /* SDV GT2 server */
+       INTEL_VGA_DEVICE(0x0C2A, &intel_haswell_d_info), /* SDV GT3 server */
        INTEL_VGA_DEVICE(0x0C06, &intel_haswell_m_info), /* SDV GT1 mobile */
        INTEL_VGA_DEVICE(0x0C16, &intel_haswell_m_info), /* SDV GT2 mobile */
-       INTEL_VGA_DEVICE(0x0C26, &intel_haswell_m_info), /* SDV GT2 mobile */
+       INTEL_VGA_DEVICE(0x0C26, &intel_haswell_m_info), /* SDV GT3 mobile */
+       INTEL_VGA_DEVICE(0x0C0B, &intel_haswell_d_info), /* SDV GT1 reserved */
+       INTEL_VGA_DEVICE(0x0C1B, &intel_haswell_d_info), /* SDV GT2 reserved */
+       INTEL_VGA_DEVICE(0x0C2B, &intel_haswell_d_info), /* SDV GT3 reserved */
+       INTEL_VGA_DEVICE(0x0C0E, &intel_haswell_d_info), /* SDV GT1 reserved */
+       INTEL_VGA_DEVICE(0x0C1E, &intel_haswell_d_info), /* SDV GT2 reserved */
+       INTEL_VGA_DEVICE(0x0C2E, &intel_haswell_d_info), /* SDV GT3 reserved */
        INTEL_VGA_DEVICE(0x0A02, &intel_haswell_d_info), /* ULT GT1 desktop */
        INTEL_VGA_DEVICE(0x0A12, &intel_haswell_d_info), /* ULT GT2 desktop */
-       INTEL_VGA_DEVICE(0x0A22, &intel_haswell_d_info), /* ULT GT2 desktop */
+       INTEL_VGA_DEVICE(0x0A22, &intel_haswell_d_info), /* ULT GT3 desktop */
        INTEL_VGA_DEVICE(0x0A0A, &intel_haswell_d_info), /* ULT GT1 server */
        INTEL_VGA_DEVICE(0x0A1A, &intel_haswell_d_info), /* ULT GT2 server */
-       INTEL_VGA_DEVICE(0x0A2A, &intel_haswell_d_info), /* ULT GT2 server */
+       INTEL_VGA_DEVICE(0x0A2A, &intel_haswell_d_info), /* ULT GT3 server */
        INTEL_VGA_DEVICE(0x0A06, &intel_haswell_m_info), /* ULT GT1 mobile */
        INTEL_VGA_DEVICE(0x0A16, &intel_haswell_m_info), /* ULT GT2 mobile */
-       INTEL_VGA_DEVICE(0x0A26, &intel_haswell_m_info), /* ULT GT2 mobile */
+       INTEL_VGA_DEVICE(0x0A26, &intel_haswell_m_info), /* ULT GT3 mobile */
+       INTEL_VGA_DEVICE(0x0A0B, &intel_haswell_d_info), /* ULT GT1 reserved */
+       INTEL_VGA_DEVICE(0x0A1B, &intel_haswell_d_info), /* ULT GT2 reserved */
+       INTEL_VGA_DEVICE(0x0A2B, &intel_haswell_d_info), /* ULT GT3 reserved */
+       INTEL_VGA_DEVICE(0x0A0E, &intel_haswell_m_info), /* ULT GT1 reserved */
+       INTEL_VGA_DEVICE(0x0A1E, &intel_haswell_m_info), /* ULT GT2 reserved */
+       INTEL_VGA_DEVICE(0x0A2E, &intel_haswell_m_info), /* ULT GT3 reserved */
        INTEL_VGA_DEVICE(0x0D02, &intel_haswell_d_info), /* CRW GT1 desktop */
        INTEL_VGA_DEVICE(0x0D12, &intel_haswell_d_info), /* CRW GT2 desktop */
-       INTEL_VGA_DEVICE(0x0D22, &intel_haswell_d_info), /* CRW GT2 desktop */
+       INTEL_VGA_DEVICE(0x0D22, &intel_haswell_d_info), /* CRW GT3 desktop */
        INTEL_VGA_DEVICE(0x0D0A, &intel_haswell_d_info), /* CRW GT1 server */
        INTEL_VGA_DEVICE(0x0D1A, &intel_haswell_d_info), /* CRW GT2 server */
-       INTEL_VGA_DEVICE(0x0D2A, &intel_haswell_d_info), /* CRW GT2 server */
+       INTEL_VGA_DEVICE(0x0D2A, &intel_haswell_d_info), /* CRW GT3 server */
        INTEL_VGA_DEVICE(0x0D06, &intel_haswell_m_info), /* CRW GT1 mobile */
        INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT2 mobile */
-       INTEL_VGA_DEVICE(0x0D26, &intel_haswell_m_info), /* CRW GT2 mobile */
+       INTEL_VGA_DEVICE(0x0D26, &intel_haswell_m_info), /* CRW GT3 mobile */
+       INTEL_VGA_DEVICE(0x0D0B, &intel_haswell_d_info), /* CRW GT1 reserved */
+       INTEL_VGA_DEVICE(0x0D1B, &intel_haswell_d_info), /* CRW GT2 reserved */
+       INTEL_VGA_DEVICE(0x0D2B, &intel_haswell_d_info), /* CRW GT3 reserved */
+       INTEL_VGA_DEVICE(0x0D0E, &intel_haswell_d_info), /* CRW GT1 reserved */
+       INTEL_VGA_DEVICE(0x0D1E, &intel_haswell_d_info), /* CRW GT2 reserved */
+       INTEL_VGA_DEVICE(0x0D2E, &intel_haswell_d_info), /* CRW GT3 reserved */
        INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info),
        INTEL_VGA_DEVICE(0x0f31, &intel_valleyview_m_info),
        INTEL_VGA_DEVICE(0x0f32, &intel_valleyview_m_info),
index d5dcf7f..b9d00dc 100644 (file)
@@ -1943,4 +1943,19 @@ static inline void __user *to_user_ptr(u64 address)
        return (void __user *)(uintptr_t)address;
 }
 
+static inline unsigned long msecs_to_jiffies_timeout(const unsigned int m)
+{
+       unsigned long j = msecs_to_jiffies(m);
+
+       return min_t(unsigned long, MAX_JIFFY_OFFSET, j + 1);
+}
+
+static inline unsigned long
+timespec_to_jiffies_timeout(const struct timespec *value)
+{
+       unsigned long j = timespec_to_jiffies(value);
+
+       return min_t(unsigned long, MAX_JIFFY_OFFSET, j + 1);
+}
+
 #endif
index 6165535..a6cf8e8 100644 (file)
@@ -1003,7 +1003,7 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno,
                wait_forever = false;
        }
 
-       timeout_jiffies = timespec_to_jiffies(&wait_time);
+       timeout_jiffies = timespec_to_jiffies_timeout(&wait_time);
 
        if (WARN_ON(!ring->irq_get(ring)))
                return -ENODEV;
index efe8299..ad1117b 100644 (file)
@@ -8140,6 +8140,21 @@ static void intel_set_config_restore_state(struct drm_device *dev,
        }
 }
 
+static bool
+is_crtc_connector_off(struct drm_crtc *crtc, struct drm_connector *connectors,
+                     int num_connectors)
+{
+       int i;
+
+       for (i = 0; i < num_connectors; i++)
+               if (connectors[i].encoder &&
+                   connectors[i].encoder->crtc == crtc &&
+                   connectors[i].dpms != DRM_MODE_DPMS_ON)
+                       return true;
+
+       return false;
+}
+
 static void
 intel_set_config_compute_mode_changes(struct drm_mode_set *set,
                                      struct intel_set_config *config)
@@ -8147,7 +8162,11 @@ intel_set_config_compute_mode_changes(struct drm_mode_set *set,
 
        /* We should be able to check here if the fb has the same properties
         * and then just flip_or_move it */
-       if (set->crtc->fb != set->fb) {
+       if (set->connectors != NULL &&
+           is_crtc_connector_off(set->crtc, *set->connectors,
+                                 set->num_connectors)) {
+                       config->mode_changed = true;
+       } else if (set->crtc->fb != set->fb) {
                /* If we have no fb then treat it as a full mode set */
                if (set->crtc->fb == NULL) {
                        DRM_DEBUG_KMS("crtc has no fb, full mode set\n");
@@ -8157,8 +8176,9 @@ intel_set_config_compute_mode_changes(struct drm_mode_set *set,
                } else if (set->fb->pixel_format !=
                           set->crtc->fb->pixel_format) {
                        config->mode_changed = true;
-               } else
+               } else {
                        config->fb_changed = true;
+               }
        }
 
        if (set->fb && (set->x != set->crtc->x || set->y != set->crtc->y))
@@ -8332,11 +8352,6 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
 
                ret = intel_set_mode(set->crtc, set->mode,
                                     set->x, set->y, set->fb);
-               if (ret) {
-                       DRM_ERROR("failed to set mode on [CRTC:%d], err = %d\n",
-                                 set->crtc->base.id, ret);
-                       goto fail;
-               }
        } else if (config->fb_changed) {
                intel_crtc_wait_for_pending_flips(set->crtc);
 
@@ -8344,18 +8359,18 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
                                          set->x, set->y, set->fb);
        }
 
-       intel_set_config_free(config);
-
-       return 0;
-
+       if (ret) {
+               DRM_ERROR("failed to set mode on [CRTC:%d], err = %d\n",
+                         set->crtc->base.id, ret);
 fail:
-       intel_set_config_restore_state(dev, config);
+               intel_set_config_restore_state(dev, config);
 
-       /* Try to restore the config */
-       if (config->mode_changed &&
-           intel_set_mode(save_set.crtc, save_set.mode,
-                          save_set.x, save_set.y, save_set.fb))
-               DRM_ERROR("failed to restore config after modeset failure\n");
+               /* Try to restore the config */
+               if (config->mode_changed &&
+                   intel_set_mode(save_set.crtc, save_set.mode,
+                                  save_set.x, save_set.y, save_set.fb))
+                       DRM_ERROR("failed to restore config after modeset failure\n");
+       }
 
 out_config:
        intel_set_config_free(config);
index 3d704b7..70789b1 100644 (file)
@@ -303,7 +303,7 @@ intel_dp_aux_wait_done(struct intel_dp *intel_dp, bool has_aux_irq)
 #define C (((status = I915_READ_NOTRACE(ch_ctl)) & DP_AUX_CH_CTL_SEND_BUSY) == 0)
        if (has_aux_irq)
                done = wait_event_timeout(dev_priv->gmbus_wait_queue, C,
-                                         msecs_to_jiffies(10));
+                                         msecs_to_jiffies_timeout(10));
        else
                done = wait_for_atomic(C, 10) == 0;
        if (!done)
index 5d24503..639fe19 100644 (file)
@@ -228,7 +228,7 @@ gmbus_wait_hw_status(struct drm_i915_private *dev_priv,
         * need to wake up periodically and check that ourselves. */
        I915_WRITE(GMBUS4 + reg_offset, gmbus4_irq_en);
 
-       for (i = 0; i < msecs_to_jiffies(50) + 1; i++) {
+       for (i = 0; i < msecs_to_jiffies_timeout(50); i++) {
                prepare_to_wait(&dev_priv->gmbus_wait_queue, &wait,
                                TASK_UNINTERRUPTIBLE);
 
@@ -263,7 +263,8 @@ gmbus_wait_idle(struct drm_i915_private *dev_priv)
        /* Important: The hw handles only the first bit, so set only one! */
        I915_WRITE(GMBUS4 + reg_offset, GMBUS_IDLE_EN);
 
-       ret = wait_event_timeout(dev_priv->gmbus_wait_queue, C, 10);
+       ret = wait_event_timeout(dev_priv->gmbus_wait_queue, C,
+                                msecs_to_jiffies_timeout(10));
 
        I915_WRITE(GMBUS4 + reg_offset, 0);