aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDeepak S <deepak.s@intel.com>2014-01-30 12:38:16 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-02-04 05:59:19 -0500
commit76c3552f9f65005f406cbffe95b981e30ef51428 (patch)
tree3fd18f85d5b3ed1a3dfac1d9e025e6f2b40bea2d
parent939fd762083f988be271da8c96398178daf9baf0 (diff)
drm/i915/vlv: WA to fix Voltage not getting dropped to Vmin when Gfx is power gated.
When we enter RC6 and GFX Clocks are off, the voltage remains higher than Vmin. When we try to set the freq to RPn, it might fail since the Gfx clocks are down. So to fix this in Gfx idle, Bring the GFX clock up and set the freq to RPn then move GFx down. v2: remove vlv_update_rps_cur_delay function. Update commit message (Daniel) v3: Fix the timeout during wait for gfx clock (Jesse) v4: addressed comments on set freq and punit wait (Ville) v5: use wait_for while waiting for GFX clk to be up. (Daniel) update cur_delay before requesting min_delay. (Ville) v6: use wait_for while waiting for punit. (Ville) Signed-off-by: Deepak S <deepak.s@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h2
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c2
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h4
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c55
4 files changed, 61 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index fa37dfdad4e3..e908c9910640 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1984,6 +1984,8 @@ extern void intel_console_resume(struct work_struct *work);
1984void i915_queue_hangcheck(struct drm_device *dev); 1984void i915_queue_hangcheck(struct drm_device *dev);
1985void i915_handle_error(struct drm_device *dev, bool wedged); 1985void i915_handle_error(struct drm_device *dev, bool wedged);
1986 1986
1987void gen6_set_pm_mask(struct drm_i915_private *dev_priv, u32 pm_iir,
1988 int new_delay);
1987extern void intel_irq_init(struct drm_device *dev); 1989extern void intel_irq_init(struct drm_device *dev);
1988extern void intel_hpd_init(struct drm_device *dev); 1990extern void intel_hpd_init(struct drm_device *dev);
1989 1991
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index ec9eec4ce952..56edff3bbbb9 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -986,7 +986,7 @@ static void notify_ring(struct drm_device *dev,
986 i915_queue_hangcheck(dev); 986 i915_queue_hangcheck(dev);
987} 987}
988 988
989static void gen6_set_pm_mask(struct drm_i915_private *dev_priv, 989void gen6_set_pm_mask(struct drm_i915_private *dev_priv,
990 u32 pm_iir, int new_delay) 990 u32 pm_iir, int new_delay)
991{ 991{
992 if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) { 992 if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) {
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index abd18cd58aa1..9d0f4f7bbe6a 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4951,6 +4951,10 @@
4951 GEN6_PM_RP_DOWN_THRESHOLD | \ 4951 GEN6_PM_RP_DOWN_THRESHOLD | \
4952 GEN6_PM_RP_DOWN_TIMEOUT) 4952 GEN6_PM_RP_DOWN_TIMEOUT)
4953 4953
4954#define VLV_GTLC_SURVIVABILITY_REG 0x130098
4955#define VLV_GFX_CLK_STATUS_BIT (1<<3)
4956#define VLV_GFX_CLK_FORCE_ON_BIT (1<<2)
4957
4954#define GEN6_GT_GFX_RC6_LOCKED 0x138104 4958#define GEN6_GT_GFX_RC6_LOCKED 0x138104
4955#define VLV_COUNTER_CONTROL 0x138104 4959#define VLV_COUNTER_CONTROL 0x138104
4956#define VLV_COUNT_RANGE_HIGH (1<<15) 4960#define VLV_COUNT_RANGE_HIGH (1<<15)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index df18bb6ffb6f..9ab388313d3d 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3038,6 +3038,58 @@ void gen6_set_rps(struct drm_device *dev, u8 val)
3038 trace_intel_gpu_freq_change(val * 50); 3038 trace_intel_gpu_freq_change(val * 50);
3039} 3039}
3040 3040
3041/* vlv_set_rps_idle: Set the frequency to Rpn if Gfx clocks are down
3042 *
3043 * * If Gfx is Idle, then
3044 * 1. Mask Turbo interrupts
3045 * 2. Bring up Gfx clock
3046 * 3. Change the freq to Rpn and wait till P-Unit updates freq
3047 * 4. Clear the Force GFX CLK ON bit so that Gfx can down
3048 * 5. Unmask Turbo interrupts
3049*/
3050static void vlv_set_rps_idle(struct drm_i915_private *dev_priv)
3051{
3052 /*
3053 * When we are idle. Drop to min voltage state.
3054 */
3055
3056 if (dev_priv->rps.cur_delay <= dev_priv->rps.min_delay)
3057 return;
3058
3059 /* Mask turbo interrupt so that they will not come in between */
3060 I915_WRITE(GEN6_PMINTRMSK, 0xffffffff);
3061
3062 /* Bring up the Gfx clock */
3063 I915_WRITE(VLV_GTLC_SURVIVABILITY_REG,
3064 I915_READ(VLV_GTLC_SURVIVABILITY_REG) |
3065 VLV_GFX_CLK_FORCE_ON_BIT);
3066
3067 if (wait_for(((VLV_GFX_CLK_STATUS_BIT &
3068 I915_READ(VLV_GTLC_SURVIVABILITY_REG)) != 0), 5)) {
3069 DRM_ERROR("GFX_CLK_ON request timed out\n");
3070 return;
3071 }
3072
3073 dev_priv->rps.cur_delay = dev_priv->rps.min_delay;
3074
3075 vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ,
3076 dev_priv->rps.min_delay);
3077
3078 if (wait_for(((vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS))
3079 & GENFREQSTATUS) == 0, 5))
3080 DRM_ERROR("timed out waiting for Punit\n");
3081
3082 /* Release the Gfx clock */
3083 I915_WRITE(VLV_GTLC_SURVIVABILITY_REG,
3084 I915_READ(VLV_GTLC_SURVIVABILITY_REG) &
3085 ~VLV_GFX_CLK_FORCE_ON_BIT);
3086
3087 /* Unmask Up interrupts */
3088 dev_priv->rps.rp_up_masked = true;
3089 gen6_set_pm_mask(dev_priv, GEN6_PM_RP_DOWN_THRESHOLD,
3090 dev_priv->rps.min_delay);
3091}
3092
3041void gen6_rps_idle(struct drm_i915_private *dev_priv) 3093void gen6_rps_idle(struct drm_i915_private *dev_priv)
3042{ 3094{
3043 struct drm_device *dev = dev_priv->dev; 3095 struct drm_device *dev = dev_priv->dev;
@@ -3045,7 +3097,7 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv)
3045 mutex_lock(&dev_priv->rps.hw_lock); 3097 mutex_lock(&dev_priv->rps.hw_lock);
3046 if (dev_priv->rps.enabled) { 3098 if (dev_priv->rps.enabled) {
3047 if (IS_VALLEYVIEW(dev)) 3099 if (IS_VALLEYVIEW(dev))
3048 valleyview_set_rps(dev_priv->dev, dev_priv->rps.min_delay); 3100 vlv_set_rps_idle(dev_priv);
3049 else 3101 else
3050 gen6_set_rps(dev_priv->dev, dev_priv->rps.min_delay); 3102 gen6_set_rps(dev_priv->dev, dev_priv->rps.min_delay);
3051 dev_priv->rps.last_adj = 0; 3103 dev_priv->rps.last_adj = 0;
@@ -4276,6 +4328,7 @@ void intel_gpu_ips_teardown(void)
4276 i915_mch_dev = NULL; 4328 i915_mch_dev = NULL;
4277 spin_unlock_irq(&mchdev_lock); 4329 spin_unlock_irq(&mchdev_lock);
4278} 4330}
4331
4279static void intel_init_emon(struct drm_device *dev) 4332static void intel_init_emon(struct drm_device *dev)
4280{ 4333{
4281 struct drm_i915_private *dev_priv = dev->dev_private; 4334 struct drm_i915_private *dev_priv = dev->dev_private;