Merge tag 'drm-intel-next-fixes-2014-12-11' of git://anongit.freedesktop.org/drm...
authorDave Airlie <airlied@redhat.com>
Fri, 12 Dec 2014 01:39:49 +0000 (11:39 +1000)
committerDave Airlie <airlied@redhat.com>
Fri, 12 Dec 2014 01:39:49 +0000 (11:39 +1000)
Here's a batch of i915 fixes for 3.19.

* tag 'drm-intel-next-fixes-2014-12-11' of git://anongit.freedesktop.org/drm-intel:
  drm/i915: save/restore GMBUS freq across suspend/resume on gen4
  drm/i915: Remove '& 0xffff' from the mask given to WA_REG()
  drm/i915: Invert the mask and val arguments in wa_add() and WA_REG()
  drm/i915/bdw: Fix the write setting up the WIZ hashing mode
  drm/i915: Don't complain about stolen conflicts on gen3
  drm/i915: resume MST after reading back hw state
  drm/i915: Handle inaccurate time conversion issues
  drm/i915: compute wait_ioctl timeout correctly
  drm/i915: don't always do full mode sets when infoframes are enabled

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/i915_gem_stolen.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/i915_suspend.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/i915/intel_ringbuffer.c
kernel/time/time.c

index 1e9c136..f990ab4 100644 (file)
@@ -706,11 +706,12 @@ static int i915_drm_resume(struct drm_device *dev)
                        dev_priv->display.hpd_irq_setup(dev);
                spin_unlock_irq(&dev_priv->irq_lock);
 
-               intel_dp_mst_resume(dev);
                drm_modeset_lock_all(dev);
                intel_modeset_setup_hw_state(dev, true);
                drm_modeset_unlock_all(dev);
 
+               intel_dp_mst_resume(dev);
+
                /*
                 * ... but also need to make sure that hotplug processing
                 * doesn't cause havoc. Like in the driver load code we don't
index bb1892d..63bcda5 100644 (file)
@@ -924,6 +924,7 @@ struct i915_suspend_saved_registers {
        u32 savePIPEB_LINK_N1;
        u32 saveMCHBAR_RENDER_STANDBY;
        u32 savePCH_PORT_HOTPLUG;
+       u16 saveGCDGMBUS;
 };
 
 struct vlv_s0ix_state {
@@ -3032,6 +3033,11 @@ static inline unsigned long msecs_to_jiffies_timeout(const unsigned int m)
        return min_t(unsigned long, MAX_JIFFY_OFFSET, j + 1);
 }
 
+static inline unsigned long nsecs_to_jiffies_timeout(const u64 n)
+{
+        return min_t(u64, MAX_JIFFY_OFFSET, nsecs_to_jiffies64(n) + 1);
+}
+
 static inline unsigned long
 timespec_to_jiffies_timeout(const struct timespec *value)
 {
index d2ba315..4a9faea 100644 (file)
@@ -1227,7 +1227,8 @@ int __i915_wait_seqno(struct intel_engine_cs *ring, u32 seqno,
        if (i915_seqno_passed(ring->get_seqno(ring, true), seqno))
                return 0;
 
-       timeout_expire = timeout ? jiffies + nsecs_to_jiffies((u64)*timeout) : 0;
+       timeout_expire = timeout ?
+               jiffies + nsecs_to_jiffies_timeout((u64)*timeout) : 0;
 
        if (INTEL_INFO(dev)->gen >= 6 && ring->id == RCS && can_wait_boost(file_priv)) {
                gen6_rps_boost(dev_priv);
@@ -1303,6 +1304,16 @@ int __i915_wait_seqno(struct intel_engine_cs *ring, u32 seqno,
                s64 tres = *timeout - (now - before);
 
                *timeout = tres < 0 ? 0 : tres;
+
+               /*
+                * Apparently ktime isn't accurate enough and occasionally has a
+                * bit of mismatch in the jiffies<->nsecs<->ktime loop. So patch
+                * things up to make the test happy. We allow up to 1 jiffy.
+                *
+                * This is a regrssion from the timespec->ktime conversion.
+                */
+               if (ret == -ETIME && *timeout < jiffies_to_usecs(1)*1000)
+                       *timeout = 0;
        }
 
        return ret;
index c388918..a204584 100644 (file)
@@ -137,7 +137,11 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev)
                r = devm_request_mem_region(dev->dev, base + 1,
                                            dev_priv->gtt.stolen_size - 1,
                                            "Graphics Stolen Memory");
-               if (r == NULL) {
+               /*
+                * GEN3 firmware likes to smash pci bridges into the stolen
+                * range. Apparently this works.
+                */
+               if (r == NULL && !IS_GEN3(dev)) {
                        DRM_ERROR("conflict detected with stolen region: [0x%08x - 0x%08x]\n",
                                  base, base + (uint32_t)dev_priv->gtt.stolen_size);
                        base = 0;
index 5446758..eefdc23 100644 (file)
 #define _PIPE3(pipe, a, b, c) ((pipe) == PIPE_A ? (a) : \
                               (pipe) == PIPE_B ? (b) : (c))
 
-#define _MASKED_BIT_ENABLE(a) (((a) << 16) | (a))
-#define _MASKED_BIT_DISABLE(a) ((a) << 16)
+#define _MASKED_FIELD(mask, value) ({                                     \
+       if (__builtin_constant_p(mask))                                    \
+               BUILD_BUG_ON_MSG(((mask) & 0xffff0000), "Incorrect mask"); \
+       if (__builtin_constant_p(value))                                   \
+               BUILD_BUG_ON_MSG((value) & 0xffff0000, "Incorrect value"); \
+       if (__builtin_constant_p(mask) && __builtin_constant_p(value))     \
+               BUILD_BUG_ON_MSG((value) & ~(mask),                        \
+                                "Incorrect value for mask");              \
+       (mask) << 16 | (value); })
+#define _MASKED_BIT_ENABLE(a)  ({ typeof(a) _a = (a); _MASKED_FIELD(_a, _a); })
+#define _MASKED_BIT_DISABLE(a) (_MASKED_FIELD((a), 0))
+
+
 
 /* PCI config space */
 
@@ -74,6 +85,7 @@
 #define   I915_GC_RENDER_CLOCK_166_MHZ (0 << 0)
 #define   I915_GC_RENDER_CLOCK_200_MHZ (1 << 0)
 #define   I915_GC_RENDER_CLOCK_333_MHZ (4 << 0)
+#define GCDGMBUS 0xcc
 #define PCI_LBPC 0xf4 /* legacy/combination backlight modes, also called LBB */
 
 
@@ -1282,7 +1294,7 @@ enum punit_power_well {
 #define   GEN6_WIZ_HASHING_8x8                         GEN6_WIZ_HASHING(0, 0)
 #define   GEN6_WIZ_HASHING_8x4                         GEN6_WIZ_HASHING(0, 1)
 #define   GEN6_WIZ_HASHING_16x4                                GEN6_WIZ_HASHING(1, 0)
-#define   GEN6_WIZ_HASHING_MASK                                (GEN6_WIZ_HASHING(1, 1) << 16)
+#define   GEN6_WIZ_HASHING_MASK                                GEN6_WIZ_HASHING(1, 1)
 #define   GEN6_TD_FOUR_ROW_DISPATCH_DISABLE            (1 << 5)
 
 #define GFX_MODE       0x02520
index dfe6617..2636882 100644 (file)
@@ -303,6 +303,10 @@ int i915_save_state(struct drm_device *dev)
                }
        }
 
+       if (IS_GEN4(dev))
+               pci_read_config_word(dev->pdev, GCDGMBUS,
+                                    &dev_priv->regfile.saveGCDGMBUS);
+
        /* Cache mode state */
        if (INTEL_INFO(dev)->gen < 7)
                dev_priv->regfile.saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
@@ -331,6 +335,10 @@ int i915_restore_state(struct drm_device *dev)
        mutex_lock(&dev->struct_mutex);
 
        i915_gem_restore_fences(dev);
+
+       if (IS_GEN4(dev))
+               pci_write_config_word(dev->pdev, GCDGMBUS,
+                                     dev_priv->regfile.saveGCDGMBUS);
        i915_restore_display(dev);
 
        if (!drm_core_check_feature(dev, DRIVER_MODESET)) {
index 63247c6..fb3e3d4 100644 (file)
@@ -11580,10 +11580,12 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
                    to_intel_crtc(set->crtc)->config.has_audio)
                        config->mode_changed = true;
 
-               /* Force mode sets for any infoframe stuff */
-               if (pipe_config->has_infoframe ||
-                   to_intel_crtc(set->crtc)->config.has_infoframe)
-                       config->mode_changed = true;
+               /*
+                * Note we have an issue here with infoframes: current code
+                * only updates them on the full mode set path per hw
+                * requirements.  So here we should be checking for any
+                * required changes and forcing a mode set.
+                */
        }
 
        /* set_mode will free it in the mode_changed case */
index 9af0af4..1f4b56e 100644 (file)
@@ -6508,7 +6508,7 @@ static void gen6_init_clock_gating(struct drm_device *dev)
         * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
         */
        I915_WRITE(GEN6_GT_MODE,
-                  GEN6_WIZ_HASHING_MASK | GEN6_WIZ_HASHING_16x4);
+                  _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4));
 
        ilk_init_lp_watermarks(dev);
 
@@ -6706,7 +6706,7 @@ static void haswell_init_clock_gating(struct drm_device *dev)
         * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
         */
        I915_WRITE(GEN7_GT_MODE,
-                  GEN6_WIZ_HASHING_MASK | GEN6_WIZ_HASHING_16x4);
+                  _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4));
 
        /* WaSwitchSolVfFArbitrationPriority:hsw */
        I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL);
@@ -6803,7 +6803,7 @@ static void ivybridge_init_clock_gating(struct drm_device *dev)
         * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
         */
        I915_WRITE(GEN7_GT_MODE,
-                  GEN6_WIZ_HASHING_MASK | GEN6_WIZ_HASHING_16x4);
+                  _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4));
 
        snpcr = I915_READ(GEN6_MBCUNIT_SNPCR);
        snpcr &= ~GEN6_MBC_SNPCR_MASK;
index 1d01b51..9f445e9 100644 (file)
@@ -701,7 +701,7 @@ static int intel_ring_workarounds_emit(struct intel_engine_cs *ring,
 }
 
 static int wa_add(struct drm_i915_private *dev_priv,
-                 const u32 addr, const u32 val, const u32 mask)
+                 const u32 addr, const u32 mask, const u32 val)
 {
        const u32 idx = dev_priv->workarounds.count;
 
@@ -717,22 +717,25 @@ static int wa_add(struct drm_i915_private *dev_priv,
        return 0;
 }
 
-#define WA_REG(addr, val, mask) { \
-               const int r = wa_add(dev_priv, (addr), (val), (mask)); \
+#define WA_REG(addr, mask, val) { \
+               const int r = wa_add(dev_priv, (addr), (mask), (val)); \
                if (r) \
                        return r; \
        }
 
 #define WA_SET_BIT_MASKED(addr, mask) \
-       WA_REG(addr, _MASKED_BIT_ENABLE(mask), (mask) & 0xffff)
+       WA_REG(addr, (mask), _MASKED_BIT_ENABLE(mask))
 
 #define WA_CLR_BIT_MASKED(addr, mask) \
-       WA_REG(addr, _MASKED_BIT_DISABLE(mask), (mask) & 0xffff)
+       WA_REG(addr, (mask), _MASKED_BIT_DISABLE(mask))
 
-#define WA_SET_BIT(addr, mask) WA_REG(addr, I915_READ(addr) | (mask), mask)
-#define WA_CLR_BIT(addr, mask) WA_REG(addr, I915_READ(addr) & ~(mask), mask)
+#define WA_SET_FIELD_MASKED(addr, mask, value) \
+       WA_REG(addr, mask, _MASKED_FIELD(mask, value))
 
-#define WA_WRITE(addr, val) WA_REG(addr, val, 0xffffffff)
+#define WA_SET_BIT(addr, mask) WA_REG(addr, mask, I915_READ(addr) | (mask))
+#define WA_CLR_BIT(addr, mask) WA_REG(addr, mask, I915_READ(addr) & ~(mask))
+
+#define WA_WRITE(addr, val) WA_REG(addr, 0xffffffff, val)
 
 static int bdw_init_workarounds(struct intel_engine_cs *ring)
 {
@@ -773,8 +776,9 @@ static int bdw_init_workarounds(struct intel_engine_cs *ring)
         * disable bit, which we don't touch here, but it's good
         * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
         */
-       WA_SET_BIT_MASKED(GEN7_GT_MODE,
-                         GEN6_WIZ_HASHING_MASK | GEN6_WIZ_HASHING_16x4);
+       WA_SET_FIELD_MASKED(GEN7_GT_MODE,
+                           GEN6_WIZ_HASHING_MASK,
+                           GEN6_WIZ_HASHING_16x4);
 
        return 0;
 }
index a9ae20f..8fae82c 100644 (file)
@@ -745,6 +745,7 @@ u64 nsecs_to_jiffies64(u64 n)
        return div_u64(n * 9, (9ull * NSEC_PER_SEC + HZ / 2) / HZ);
 #endif
 }
+EXPORT_SYMBOL(nsecs_to_jiffies64);
 
 /**
  * nsecs_to_jiffies - Convert nsecs in u64 to jiffies