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.salo...@intel.com>
Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com>
---
 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@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to