aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_pm.c
diff options
context:
space:
mode:
authorImre Deak <imre.deak@intel.com>2014-03-31 08:10:44 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-04-01 16:30:01 -0400
commitae48434c2a13cf4758aaf87da21d828f6d4dbebb (patch)
tree0162c5b1cb050f28747f1558139220ed5d47f75d /drivers/gpu/drm/i915/intel_pm.c
parent50227e1cae118562b8b6230e31bca84870cad27e (diff)
drm/i915: vlv: reserve the GT power context only once during driver init
Atm we reserve/allocate and free the power context during GT power enable/disable time. There is no need to do this, we can reserve/allocate the buffer once during driver loading and free it during driver cleanup. The re-reservation can also fail in case the driver previously manages to allocate something on the given fixed address. The buffer isn't exepected to move even if allocated by the BIOS, for safety add an assert to check this assumption. This also fixed a bug for Ville, where re-reserving the context failed during a GPU reset (I assume because something else got allocated on its fixed address). Tested-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pm.c')
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c41
1 files changed, 34 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 38a68cea5ed7..453bf0cc21c0 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3201,11 +3201,6 @@ static void valleyview_disable_rps(struct drm_device *dev)
3201 I915_WRITE(GEN6_RC_CONTROL, 0); 3201 I915_WRITE(GEN6_RC_CONTROL, 0);
3202 3202
3203 gen6_disable_rps_interrupts(dev); 3203 gen6_disable_rps_interrupts(dev);
3204
3205 if (dev_priv->vlv_pctx) {
3206 drm_gem_object_unreference(&dev_priv->vlv_pctx->base);
3207 dev_priv->vlv_pctx = NULL;
3208 }
3209} 3204}
3210 3205
3211static void intel_print_rc6_info(struct drm_device *dev, u32 mode) 3206static void intel_print_rc6_info(struct drm_device *dev, u32 mode)
@@ -3549,6 +3544,15 @@ int valleyview_rps_min_freq(struct drm_i915_private *dev_priv)
3549 return vlv_punit_read(dev_priv, PUNIT_REG_GPU_LFM) & 0xff; 3544 return vlv_punit_read(dev_priv, PUNIT_REG_GPU_LFM) & 0xff;
3550} 3545}
3551 3546
3547/* Check that the pctx buffer wasn't move under us. */
3548static void valleyview_check_pctx(struct drm_i915_private *dev_priv)
3549{
3550 unsigned long pctx_addr = I915_READ(VLV_PCBR) & ~4095;
3551
3552 WARN_ON(pctx_addr != dev_priv->mm.stolen_base +
3553 dev_priv->vlv_pctx->stolen->start);
3554}
3555
3552static void valleyview_setup_pctx(struct drm_device *dev) 3556static void valleyview_setup_pctx(struct drm_device *dev)
3553{ 3557{
3554 struct drm_i915_private *dev_priv = dev->dev_private; 3558 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -3593,6 +3597,17 @@ out:
3593 dev_priv->vlv_pctx = pctx; 3597 dev_priv->vlv_pctx = pctx;
3594} 3598}
3595 3599
3600static void valleyview_cleanup_pctx(struct drm_device *dev)
3601{
3602 struct drm_i915_private *dev_priv = dev->dev_private;
3603
3604 if (WARN_ON(!dev_priv->vlv_pctx))
3605 return;
3606
3607 drm_gem_object_unreference(&dev_priv->vlv_pctx->base);
3608 dev_priv->vlv_pctx = NULL;
3609}
3610
3596static void valleyview_enable_rps(struct drm_device *dev) 3611static void valleyview_enable_rps(struct drm_device *dev)
3597{ 3612{
3598 struct drm_i915_private *dev_priv = dev->dev_private; 3613 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -3602,6 +3617,8 @@ static void valleyview_enable_rps(struct drm_device *dev)
3602 3617
3603 WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); 3618 WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
3604 3619
3620 valleyview_check_pctx(dev_priv);
3621
3605 if ((gtfifodbg = I915_READ(GTFIFODBG))) { 3622 if ((gtfifodbg = I915_READ(GTFIFODBG))) {
3606 DRM_DEBUG_DRIVER("GT fifo had a previous error %x\n", 3623 DRM_DEBUG_DRIVER("GT fifo had a previous error %x\n",
3607 gtfifodbg); 3624 gtfifodbg);
@@ -4418,6 +4435,18 @@ static void intel_init_emon(struct drm_device *dev)
4418 dev_priv->ips.corr = (lcfuse & LCFUSE_HIV_MASK); 4435 dev_priv->ips.corr = (lcfuse & LCFUSE_HIV_MASK);
4419} 4436}
4420 4437
4438void intel_init_gt_powersave(struct drm_device *dev)
4439{
4440 if (IS_VALLEYVIEW(dev))
4441 valleyview_setup_pctx(dev);
4442}
4443
4444void intel_cleanup_gt_powersave(struct drm_device *dev)
4445{
4446 if (IS_VALLEYVIEW(dev))
4447 valleyview_cleanup_pctx(dev);
4448}
4449
4421void intel_disable_gt_powersave(struct drm_device *dev) 4450void intel_disable_gt_powersave(struct drm_device *dev)
4422{ 4451{
4423 struct drm_i915_private *dev_priv = dev->dev_private; 4452 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -4472,8 +4501,6 @@ void intel_enable_gt_powersave(struct drm_device *dev)
4472 ironlake_enable_rc6(dev); 4501 ironlake_enable_rc6(dev);
4473 intel_init_emon(dev); 4502 intel_init_emon(dev);
4474 } else if (IS_GEN6(dev) || IS_GEN7(dev)) { 4503 } else if (IS_GEN6(dev) || IS_GEN7(dev)) {
4475 if (IS_VALLEYVIEW(dev))
4476 valleyview_setup_pctx(dev);
4477 /* 4504 /*
4478 * PCU communication is slow and this doesn't need to be 4505 * PCU communication is slow and this doesn't need to be
4479 * done at any specific time, so do this out of our fast path 4506 * done at any specific time, so do this out of our fast path