On Ivybridge, we can go lower than rc6 to rc6p. And this is required for
Ivybridge to hit the same minimum power consumption as rc6 on other
platforms, so make it so.

v2: Update selftest to include all rc6 residency counters

Fixes: 730eaeb52426 ("drm/i915/gt: Manual rc6 entry upon parking")
Testcase: igt/i915_pm_rc6_residency/rc6-idle
Signed-off-by: Chris Wilson <[email protected]>
Cc: Andi Shyti <[email protected]>
Cc: Mika Kuoppala <[email protected]>
Cc: Imre Deak <[email protected]>
---
 drivers/gpu/drm/i915/gt/intel_rc6.c    | 10 +++++++++-
 drivers/gpu/drm/i915/gt/selftest_rc6.c | 21 +++++++++++++++++----
 2 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_rc6.c 
b/drivers/gpu/drm/i915/gt/intel_rc6.c
index 50aa63270cdc..09d3e5a45397 100644
--- a/drivers/gpu/drm/i915/gt/intel_rc6.c
+++ b/drivers/gpu/drm/i915/gt/intel_rc6.c
@@ -608,6 +608,7 @@ void intel_rc6_unpark(struct intel_rc6 *rc6)
 void intel_rc6_park(struct intel_rc6 *rc6)
 {
        struct intel_uncore *uncore = rc6_to_uncore(rc6);
+       unsigned int target;
 
        if (!rc6->enabled)
                return;
@@ -622,7 +623,14 @@ void intel_rc6_park(struct intel_rc6 *rc6)
 
        /* Turn off the HW timers and go directly to rc6 */
        set(uncore, GEN6_RC_CONTROL, GEN6_RC_CTL_RC6_ENABLE);
-       set(uncore, GEN6_RC_STATE, 0x4 << RC_SW_TARGET_STATE_SHIFT);
+
+       if (HAS_RC6pp(rc6_to_i915(rc6)))
+               target = 0x6; /* deepest rc6 */
+       else if (HAS_RC6p(rc6_to_i915(rc6)))
+               target = 0x5; /* deep rc6 */
+       else
+               target = 0x4; /* normal rc6 */
+       set(uncore, GEN6_RC_STATE, target << RC_SW_TARGET_STATE_SHIFT);
 }
 
 void intel_rc6_disable(struct intel_rc6 *rc6)
diff --git a/drivers/gpu/drm/i915/gt/selftest_rc6.c 
b/drivers/gpu/drm/i915/gt/selftest_rc6.c
index 5f7e2dcf5686..10720722a2ca 100644
--- a/drivers/gpu/drm/i915/gt/selftest_rc6.c
+++ b/drivers/gpu/drm/i915/gt/selftest_rc6.c
@@ -12,6 +12,19 @@
 
 #include "selftests/i915_random.h"
 
+static u64 rc6_residency(struct intel_rc6 *rc6)
+{
+       u64 result;
+
+       result = intel_rc6_residency_ns(rc6, GEN6_GT_GFX_RC6);
+       if (HAS_RC6p(rc6_to_i915(rc6)))
+               result += intel_rc6_residency_ns(rc6, GEN6_GT_GFX_RC6p);
+       if (HAS_RC6pp(rc6_to_i915(rc6)))
+               result += intel_rc6_residency_ns(rc6, GEN6_GT_GFX_RC6pp);
+
+       return result;
+}
+
 int live_rc6_manual(void *arg)
 {
        struct intel_gt *gt = arg;
@@ -38,9 +51,9 @@ int live_rc6_manual(void *arg)
        __intel_rc6_disable(rc6);
        msleep(1); /* wakeup is not immediate, takes about 100us on icl */
 
-       res[0] = intel_rc6_residency_ns(rc6, GEN6_GT_GFX_RC6);
+       res[0] = rc6_residency(rc6);
        msleep(250);
-       res[1] = intel_rc6_residency_ns(rc6, GEN6_GT_GFX_RC6);
+       res[1] = rc6_residency(rc6);
        if ((res[1] - res[0]) >> 10) {
                pr_err("RC6 residency increased by %lldus while disabled for 
250ms!\n",
                       (res[1] - res[0]) >> 10);
@@ -51,9 +64,9 @@ int live_rc6_manual(void *arg)
        /* Manually enter RC6 */
        intel_rc6_park(rc6);
 
-       res[0] = intel_rc6_residency_ns(rc6, GEN6_GT_GFX_RC6);
+       res[0] = rc6_residency(rc6);
        msleep(100);
-       res[1] = intel_rc6_residency_ns(rc6, GEN6_GT_GFX_RC6);
+       res[1] = rc6_residency(rc6);
 
        if (res[1] == res[0]) {
                pr_err("Did not enter RC6! RC6_STATE=%08x, RC6_CONTROL=%08x, 
residency=%lld\n",
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to