Since RC6 enabling does not involve PCU communication overhead, it can be enabled immediately during the resume time. This will help save additional power & meet power requirements for active Idle KPI where power is evaluated over number of transitions of suspend/resume. v2: RPM ref count is not needed with immediate enabling of RC6, that is removed. And code extended to other GEN as well. (Chris & Daniel) Signed-off-by: Namrta Salonie <namrta.salonie@xxxxxxxxx> Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@xxxxxxxxx> --- drivers/gpu/drm/i915/intel_pm.c | 126 +++++++++++++++++++++++++++------------ 1 file changed, 87 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 96f45d7..1c1ea63 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4719,7 +4719,7 @@ static void gen9_enable_rc6(struct drm_device *dev) } -static void gen8_enable_rps(struct drm_device *dev) +static void gen8_enable_rc6(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *ring; @@ -4729,16 +4729,13 @@ static void gen8_enable_rps(struct drm_device *dev) /* 1a: Software RC state - RC0 */ I915_WRITE(GEN6_RC_STATE, 0); - /* 1c & 1d: Get forcewake during program sequence. Although the driver + /* 1b & 1c: Get forcewake during program sequence. Although the driver * hasn't enabled a state yet where we need forcewake, BIOS may have.*/ intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); /* 2a: Disable RC states. */ I915_WRITE(GEN6_RC_CONTROL, 0); - /* Initialize rps frequencies */ - gen6_init_rps_frequencies(dev); - /* 2b: Program RC6 thresholds.*/ I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16); I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */ @@ -4764,7 +4761,20 @@ static void gen8_enable_rps(struct drm_device *dev) GEN6_RC_CTL_EI_MODE(1) | rc6_mask); - /* 4 Program defaults and thresholds for RPS*/ + intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); +} + +static void gen8_enable_rps(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + /* 1: Get forcewake during program sequence. */ + intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); + + /* Initialize rps frequencies */ + gen6_init_rps_frequencies(dev); + + /* 2: Program defaults and thresholds for RPS*/ I915_WRITE(GEN6_RPNSWREQ, HSW_FREQUENCY(dev_priv->rps.rp1_freq)); I915_WRITE(GEN6_RC_VIDEO_FREQ, @@ -4784,7 +4794,7 @@ static void gen8_enable_rps(struct drm_device *dev) I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); - /* 5: Enable RPS */ + /* 3: Enable RPS */ I915_WRITE(GEN6_RP_CONTROL, GEN6_RP_MEDIA_TURBO | GEN6_RP_MEDIA_HW_NORMAL_MODE | @@ -4793,7 +4803,7 @@ static void gen8_enable_rps(struct drm_device *dev) GEN6_RP_UP_BUSY_AVG | GEN6_RP_DOWN_IDLE_AVG); - /* 6: Ring frequency + overclocking (our driver does this later */ + /* 4: Ring frequency + overclocking (our driver does this later */ dev_priv->rps.power = HIGH_POWER; /* force a reset */ gen6_set_rps(dev_priv->dev, dev_priv->rps.idle_freq); @@ -5320,14 +5330,13 @@ static void valleyview_cleanup_gt_powersave(struct drm_device *dev) valleyview_cleanup_pctx(dev); } -static void cherryview_enable_rps(struct drm_device *dev) +static void cherryview_enable_rc6(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *ring; - u32 gtfifodbg, val, rc6_mode = 0, pcbr; + u32 gtfifodbg, rc6_mode = 0, pcbr; int i; - WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); gtfifodbg = I915_READ(GTFIFODBG); if (gtfifodbg) { @@ -5338,7 +5347,7 @@ static void cherryview_enable_rps(struct drm_device *dev) cherryview_check_pctx(dev_priv); - /* 1a & 1b: Get forcewake during program sequence. Although the driver + /* 1: Get forcewake during program sequence. . Although the driver * hasn't enabled a state yet where we need forcewake, BIOS may have.*/ intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); @@ -5372,8 +5381,20 @@ static void cherryview_enable_rps(struct drm_device *dev) rc6_mode = GEN7_RC_CTL_TO_MODE; I915_WRITE(GEN6_RC_CONTROL, rc6_mode); + intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); +} - /* 4 Program defaults and thresholds for RPS*/ +static void cherryview_enable_rps(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + u32 val; + + WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); + + /* 1: Get forcewake during program sequence. */ + intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); + + /* 2: Program defaults and thresholds for RPS*/ I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000); I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400); I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000); @@ -5382,7 +5403,7 @@ static void cherryview_enable_rps(struct drm_device *dev) I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); - /* 5: Enable RPS */ + /* 3: Enable RPS */ I915_WRITE(GEN6_RP_CONTROL, GEN6_RP_MEDIA_HW_NORMAL_MODE | GEN6_RP_MEDIA_IS_GFX | @@ -5390,7 +5411,7 @@ static void cherryview_enable_rps(struct drm_device *dev) GEN6_RP_UP_BUSY_AVG | GEN6_RP_DOWN_IDLE_AVG); - /* Setting Fixed Bias */ + /* 4: Setting Fixed Bias */ val = VLV_OVERRIDE_EN | VLV_SOC_TDP_EN | CHV_BIAS_CPU_50_SOC_50; @@ -5418,14 +5439,13 @@ static void cherryview_enable_rps(struct drm_device *dev) intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); } -static void valleyview_enable_rps(struct drm_device *dev) +static void valleyview_enable_rc6(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *ring; - u32 gtfifodbg, val, rc6_mode = 0; + u32 gtfifodbg, rc6_mode = 0; int i; - WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); valleyview_check_pctx(dev_priv); @@ -5435,28 +5455,11 @@ static void valleyview_enable_rps(struct drm_device *dev) I915_WRITE(GTFIFODBG, gtfifodbg); } - /* If VLV, Forcewake all wells, else re-direct to regular path */ intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); /* Disable RC states. */ I915_WRITE(GEN6_RC_CONTROL, 0); - I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000); - I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400); - I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000); - I915_WRITE(GEN6_RP_UP_EI, 66000); - I915_WRITE(GEN6_RP_DOWN_EI, 350000); - - I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); - - I915_WRITE(GEN6_RP_CONTROL, - GEN6_RP_MEDIA_TURBO | - GEN6_RP_MEDIA_HW_NORMAL_MODE | - GEN6_RP_MEDIA_IS_GFX | - GEN6_RP_ENABLE | - GEN6_RP_UP_BUSY_AVG | - GEN6_RP_DOWN_IDLE_CONT); - I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 0x00280000); I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); @@ -5479,6 +5482,34 @@ static void valleyview_enable_rps(struct drm_device *dev) intel_print_rc6_info(dev, rc6_mode); I915_WRITE(GEN6_RC_CONTROL, rc6_mode); + intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); +} + +static void valleyview_enable_rps(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + u32 val; + + WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); + + /* If VLV, Forcewake all wells, else re-direct to regular path */ + intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); + + I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000); + I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400); + I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000); + I915_WRITE(GEN6_RP_UP_EI, 66000); + I915_WRITE(GEN6_RP_DOWN_EI, 350000); + + I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); + + I915_WRITE(GEN6_RP_CONTROL, + GEN6_RP_MEDIA_TURBO | + GEN6_RP_MEDIA_HW_NORMAL_MODE | + GEN6_RP_MEDIA_IS_GFX | + GEN6_RP_ENABLE | + GEN6_RP_UP_BUSY_AVG | + GEN6_RP_DOWN_IDLE_CONT); /* Setting Fixed Bias */ val = VLV_OVERRIDE_EN | @@ -6084,7 +6115,6 @@ static void intel_gen6_powersave_work(struct work_struct *work) } else if (IS_VALLEYVIEW(dev)) { valleyview_enable_rps(dev); } else if (INTEL_INFO(dev)->gen >= 9) { - gen9_enable_rc6(dev); gen9_enable_rps(dev); if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) __gen6_update_ring_freq(dev); @@ -6107,8 +6137,9 @@ static void intel_gen6_powersave_work(struct work_struct *work) gen6_enable_rps_interrupts(dev); mutex_unlock(&dev_priv->rps.hw_lock); + if (!(IS_BROADWELL(dev) || IS_GEN9(dev) || IS_VALLEYVIEW(dev))) + intel_runtime_pm_put(dev_priv); - intel_runtime_pm_put(dev_priv); } void intel_enable_gt_powersave(struct drm_device *dev) @@ -6126,6 +6157,19 @@ void intel_enable_gt_powersave(struct drm_device *dev) mutex_unlock(&dev->struct_mutex); } else if (INTEL_INFO(dev)->gen >= 6) { /* + * Enabling RC6 here itself and only deferring Turbo + * enabling. + */ + if (IS_CHERRYVIEW(dev)) + cherryview_enable_rc6(dev); + else if (IS_VALLEYVIEW(dev)) + valleyview_enable_rc6(dev); + else if (IS_BROADWELL(dev)) + gen8_enable_rc6(dev); + else if (INTEL_INFO(dev)->gen >= 9) + gen9_enable_rc6(dev); + + /* * PCU communication is slow and this doesn't need to be * done at any specific time, so do this out of our fast path * to make resume and init faster. @@ -6137,9 +6181,13 @@ void intel_enable_gt_powersave(struct drm_device *dev) * paths, so the _noresume version is enough (and in case of * runtime resume it's necessary). */ + if (schedule_delayed_work(&dev_priv->rps.delayed_resume_work, - round_jiffies_up_relative(HZ))) - intel_runtime_pm_get_noresume(dev_priv); + round_jiffies_up_relative(HZ))) { + if (!(IS_BROADWELL(dev) || IS_GEN9(dev) || IS_VALLEYVIEW(dev))) + intel_runtime_pm_get_noresume(dev_priv); + } + } } -- 1.7.9.5 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx