From af15d2ce5d497ba6535dead782cfadbcc83d90fe Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 1 Dec 2014 09:54:28 -0800 Subject: drm/i915: don't always do full mode sets when infoframes are enabled Partial revert of commit 206645910b9796bff13fcdb67bdca166b724ba62 Author: Jesse Barnes Date: Wed Nov 5 14:26:09 2014 -0800 drm/i915: check for audio and infoframe changes across mode sets v2 References: https://bugs.freedesktop.org/show_bug.cgi?id=86683 Signed-off-by: Jesse Barnes Tested-by: Li Xu Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_display.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 6289babd03b0..03d0b0cb8e05 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11583,10 +11583,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 */ -- cgit v1.2.3 From 7bd0e226e313547add65c7e4b0ecf65cb981a3c6 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 4 Dec 2014 11:12:54 +0100 Subject: drm/i915: compute wait_ioctl timeout correctly We've lost the +1 required for correct timeouts in commit 5ed0bdf21a85d78e04f89f15ccf227562177cbd9 Author: Thomas Gleixner Date: Wed Jul 16 21:05:06 2014 +0000 drm: i915: Use nsec based interfaces Use ktime_get_raw_ns() and get rid of the back and forth timespec conversions. Signed-off-by: Thomas Gleixner Acked-by: Daniel Vetter Signed-off-by: John Stultz So fix this up by reinstating our handrolled _timeout function. While at it bother with handling MAX_JIFFIES. v2: Convert to usecs (we don't care about the accuracy anyway) first to avoid overflow issues Dave Gordon spotted. v3: Drop the explicit MAX_JIFFY_OFFSET check, usecs_to_jiffies should take care of that already. It might be a bit too enthusiastic about it though. v4: Chris has a much nicer color, so use his implementation. This requires to export nsec_to_jiffies from time.c. Cc: Chris Wilson Cc: Dave Gordon Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=82749 Cc: Thomas Gleixner Cc: John Stultz Signed-off-by: Daniel Vetter Acked-by: John Stultz Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_drv.h | 5 +++++ drivers/gpu/drm/i915/i915_gem.c | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index bb1892d72efe..be910d249ea1 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3032,6 +3032,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) { diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index d2ba315f4c92..820bc984082e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -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); -- cgit v1.2.3 From 9cca30688043eb1b6569f794041dfeec218dffa5 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 28 Nov 2014 10:29:55 +0100 Subject: drm/i915: Handle inaccurate time conversion issues So apparently jiffies<->nsec<->ktime isn't accurate or something. At elast if we timeout there's occasionally still a few hundred us left (in a 2 second timeout). Stuff I've tried and thrown out again: - Sampling the before timestamp before jiffies. Doesn't improve test path rate at all. - Using jiffies. Way to inaccurate, which means way too much drift with signals plus automatic ioctl restarting in userspace. In hindsight we should have used an absolute timeout, but hey we need something for v3 of the i915 gem wait interfaces ;-) - Trying to figure out where accuracy gets lost. gl testcase really don't care all that much about this (as long as isn't not massively off), it's just that the testcase gets a bit upset if it receives an EITME with timeout > 0. So as long as we're in the ballbark it's good enough. So patch everything up if we're at most one jiffies off. I get's me a solid test again. This regression is probably introduced in commit 5ed0bdf21a85d78e04f89f15ccf227562177cbd9 Author: Thomas Gleixner Date: Wed Jul 16 21:05:06 2014 +0000 drm: i915: Use nsec based interfaces Use ktime_get_raw_ns() and get rid of the back and forth timespec conversions. Signed-off-by: Thomas Gleixner Acked-by: Daniel Vetter Signed-off-by: John Stultz Probably because I'm too lazy to confirm myself and still waiting for QA ;-) Cc: Thomas Gleixner Cc: John Stultz Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=82749 Signed-off-by: Daniel Vetter Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_gem.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 820bc984082e..4a9faea626db 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1304,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; -- cgit v1.2.3 From e7d6f7d708290da1b7c92f533444b042c79412e0 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 8 Dec 2014 13:23:37 +1000 Subject: drm/i915: resume MST after reading back hw state Otherwise the MST resume paths can hit DPMS paths which hit state checker paths, which hit WARN_ON, because the state checker is inconsistent with the hw. This fixes a bunch of WARN_ON's on resume after undocking. Signed-off-by: Dave Airlie Reviewed-by: Daniel Vetter Cc: stable@vger.kernel.org Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 1e9c136a874c..f990ab4c3efb 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -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 -- cgit v1.2.3 From 0b6d24c01932db99fc95304235e751e7f7625c41 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 11 Apr 2014 15:55:17 +0200 Subject: drm/i915: Don't complain about stolen conflicts on gen3 Apparently stuff works that way on those machines. I agree with Chris' concern that this is a bit risky but imo worth a shot in -next just for fun. Afaics all these machines have the pci resources allocated like that by the BIOS, so I suspect that it's all ok. This regression goes back to commit eaba1b8f3379b5d100bd146b9a41d28348bdfd09 Author: Chris Wilson Date: Thu Jul 4 12:28:35 2013 +0100 drm/i915: Verify that our stolen memory doesn't conflict Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=76983 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=71031 Tested-by: lu hua Signed-off-by: Daniel Vetter Reviewed-by: Jesse Barnes Tested-by: Paul Menzel Cc: stable@vger.kernel.org Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_gem_stolen.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index c38891892547..a2045848bd1a 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c @@ -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; -- cgit v1.2.3 From 98533251b0bbfa5f24c502b9ab2f01ccb25c26b8 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Mon, 8 Dec 2014 17:33:51 +0000 Subject: drm/i915/bdw: Fix the write setting up the WIZ hashing mode I was playing with clang and oh surprise! a warning trigerred by -Wshift-overflow (gcc doesn't have this one): WA_SET_BIT_MASKED(GEN7_GT_MODE, GEN6_WIZ_HASHING_MASK | GEN6_WIZ_HASHING_16x4); drivers/gpu/drm/i915/intel_ringbuffer.c:786:2: warning: signed shift result (0x28002000000) requires 43 bits to represent, but 'int' only has 32 bits [-Wshift-overflow] WA_SET_BIT_MASKED(GEN7_GT_MODE, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/gpu/drm/i915/intel_ringbuffer.c:737:15: note: expanded from macro 'WA_SET_BIT_MASKED' WA_REG(addr, _MASKED_BIT_ENABLE(mask), (mask) & 0xffff) Turned out GEN6_WIZ_HASHING_MASK was already shifted by 16, and we were trying to shift it a bit more. The other thing is that it's not the usual case of setting WA bits here, we need to have separate mask and value. To fix this, I've introduced a new _MASKED_FIELD() macro that takes both the (unshifted) mask and the desired value and the rest of the patch ripples through from it. This bug was introduced when reworking the WA emission in: Commit 7225342ab501befdb64bcec76ded41f5897c0855 Author: Mika Kuoppala Date: Tue Oct 7 17:21:26 2014 +0300 drm/i915: Build workaround list in ring initialization v2: Invert the order of the mask and value arguments (Daniel Vetter) Rewrite _MASKED_BIT_ENABLE() and _MASKED_BIT_DISABLE() with _MASKED_FIELD() (Jani Nikula) Make sure we only evaluate 'a' once in _MASKED_BIT_ENABLE() (Dave Gordon) Add check to ensure the value is within the mask boundaries (Chris Wilson) v3: Ensure the the value and mask are 16 bits (Dave Gordon) Cc: Mika Kuoppala Cc: Arun Siluvery Signed-off-by: Damien Lespiau Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_reg.h | 17 ++++++++++++++--- drivers/gpu/drm/i915/intel_pm.c | 6 +++--- drivers/gpu/drm/i915/intel_ringbuffer.c | 8 ++++++-- 3 files changed, 23 insertions(+), 8 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 544675895c8d..b607bbe55261 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -32,8 +32,19 @@ #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 */ @@ -1282,7 +1293,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 diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 9af0af49382e..1f4b56e273c8 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -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; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 1d01b51ff058..28db934b2359 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -729,6 +729,9 @@ static int wa_add(struct drm_i915_private *dev_priv, #define WA_CLR_BIT_MASKED(addr, mask) \ WA_REG(addr, _MASKED_BIT_DISABLE(mask), (mask) & 0xffff) +#define WA_SET_FIELD_MASKED(addr, mask, value) \ + WA_REG(addr, _MASKED_FIELD(mask, value), 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) @@ -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; } -- cgit v1.2.3 From cf4b0de6a3f6e1814c45206a8b175d09b265bb16 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Mon, 8 Dec 2014 17:35:37 +0000 Subject: drm/i915: Invert the mask and val arguments in wa_add() and WA_REG() While trying to unify the order of those arguments throughout the driver, Daniel noticed what we were inverting them in this part of the code. Suggested-by: Daniel Vetter Cc: Daniel Vetter Signed-off-by: Damien Lespiau Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_ringbuffer.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 28db934b2359..ef05af02763a 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -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,25 +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) & 0xffff, _MASKED_BIT_ENABLE(mask)) #define WA_CLR_BIT_MASKED(addr, mask) \ - WA_REG(addr, _MASKED_BIT_DISABLE(mask), (mask) & 0xffff) + WA_REG(addr, (mask) & 0xffff, _MASKED_BIT_DISABLE(mask)) #define WA_SET_FIELD_MASKED(addr, mask, value) \ - WA_REG(addr, _MASKED_FIELD(mask, value), mask) + WA_REG(addr, mask, _MASKED_FIELD(mask, value)) -#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_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, val, 0xffffffff) +#define WA_WRITE(addr, val) WA_REG(addr, 0xffffffff, val) static int bdw_init_workarounds(struct intel_engine_cs *ring) { -- cgit v1.2.3 From 26459343e0fac1ea4cb5192c490e3e519eed74dd Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Mon, 8 Dec 2014 17:35:38 +0000 Subject: drm/i915: Remove '& 0xffff' from the mask given to WA_REG() We may be hidding bugs by doing that, so let remove it and have the actual mask value shine through, for better or worse. Signed-off-by: Damien Lespiau Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_ringbuffer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index ef05af02763a..9f445e9a75d1 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -724,10 +724,10 @@ static int wa_add(struct drm_i915_private *dev_priv, } #define WA_SET_BIT_MASKED(addr, mask) \ - WA_REG(addr, (mask) & 0xffff, _MASKED_BIT_ENABLE(mask)) + WA_REG(addr, (mask), _MASKED_BIT_ENABLE(mask)) #define WA_CLR_BIT_MASKED(addr, mask) \ - WA_REG(addr, (mask) & 0xffff, _MASKED_BIT_DISABLE(mask)) + WA_REG(addr, (mask), _MASKED_BIT_DISABLE(mask)) #define WA_SET_FIELD_MASKED(addr, mask, value) \ WA_REG(addr, mask, _MASKED_FIELD(mask, value)) -- cgit v1.2.3 From 9f49c37635d5c2a801f7670d5fbf0b25ec461f2c Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 10 Dec 2014 12:16:05 -0800 Subject: drm/i915: save/restore GMBUS freq across suspend/resume on gen4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Should probably just init this in the GMbus code all the time, based on the cdclk and HPLL like we do on newer platforms. Ville has code for that in a rework branch, but until then we can fix this bug fairly easily. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=76301 Signed-off-by: Jesse Barnes Reviewed-by: Ville Syrjälä Tested-by: Nikolay Cc: stable@vger.kernel.org Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/i915_suspend.c | 8 ++++++++ 3 files changed, 10 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index be910d249ea1..63bcda5541ec 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -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 { diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index b607bbe55261..eefdc238f70b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -85,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 */ diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index dfe661743398..26368822a33f 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -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)) { -- cgit v1.2.3