[PATCH] drm/i915: Enabling RC6 immediately during init/resume

Namrta Salonie
2015-08-21T12:27:35Z

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.

Signed-off-by: Namrta Salonie <namrta.salonie@intel.com>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
---
drivers/gpu/drm/i915/intel_pm.c | 94 ++++++++++++++++++++++++++-------------
1 file changed, 63 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index fff0c22..f1164c0 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5468,14 +5468,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) {
@@ -5486,9 +5485,9 @@ static void cherryview_enable_rps(struct drm_device *dev)

cherryview_check_pctx(dev_priv);

- /* 1a & 1b: 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);
+ /* 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);

/* Disable RC states. */
I915_WRITE(GEN6_RC_CONTROL, 0);
@@ -5520,8 +5519,21 @@ 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. As Driver would have enabled RC6
+ * by now before Turbo enabling 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);
@@ -5530,7 +5542,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 |
@@ -5538,7 +5550,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;
@@ -5546,7 +5558,7 @@ static void cherryview_enable_rps(struct drm_device *dev)

val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);

- /* RPS code assumes GPLL is used */
+ /* 5: RPS code assumes GPLL is used */
WARN_ONCE((val & GPLLENABLE) == 0, "GPLL not enabled\n");

DRM_DEBUG_DRIVER("GPLL enabled? %s\n", val & GPLLENABLE ? "yes" : "no");
@@ -5566,14 +5578,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);

@@ -5583,28 +5594,12 @@ 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);
+ /* If VLV, Forcewake all wells */
+ 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);
@@ -5627,6 +5622,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 |
@@ -6274,6 +6297,15 @@ void intel_enable_gt_powersave(struct drm_device *dev)
mutex_unlock(&dev->struct_mutex);
} else if (INTEL_INFO(dev)->gen >= 6) {
/*
+ * Enabling RC6 for CHV/VLV here itself and only deferring Turbo
+ * enabling.
+ */
+ if (IS_CHERRYVIEW(dev))
+ cherryview_enable_rc6(dev);
+ else if (IS_VALLEYVIEW(dev))
+ valleyview_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.
--
1.7.9.5