summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/gt/intel_rc6.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/gt/intel_rc6.c')
-rw-r--r--drivers/gpu/drm/i915/gt/intel_rc6.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/gt/intel_rc6.c b/drivers/gpu/drm/i915/gt/intel_rc6.c
index f4150f61f39c..8f3cd68d14f8 100644
--- a/drivers/gpu/drm/i915/gt/intel_rc6.c
+++ b/drivers/gpu/drm/i915/gt/intel_rc6.c
@@ -420,6 +420,21 @@ static void vlv_rc6_enable(struct intel_rc6 *rc6)
GEN7_RC_CTL_TO_MODE | VLV_RC_CTL_CTX_RST_PARALLEL;
}
+bool intel_check_bios_c6_setup(struct intel_rc6 *rc6)
+{
+ if (!rc6->bios_state_captured) {
+ struct intel_uncore *uncore = rc6_to_uncore(rc6);
+ intel_wakeref_t wakeref;
+
+ with_intel_runtime_pm(uncore->rpm, wakeref)
+ rc6->bios_rc_state = intel_uncore_read(uncore, GEN6_RC_STATE);
+
+ rc6->bios_state_captured = true;
+ }
+
+ return rc6->bios_rc_state & RC_SW_TARGET_STATE_MASK;
+}
+
static bool bxt_check_bios_rc6_setup(struct intel_rc6 *rc6)
{
struct intel_uncore *uncore = rc6_to_uncore(rc6);
@@ -503,6 +518,13 @@ static bool rc6_supported(struct intel_rc6 *rc6)
return false;
}
+ if (IS_METEORLAKE(gt->i915) &&
+ !intel_check_bios_c6_setup(rc6)) {
+ drm_notice(&i915->drm,
+ "C6 disabled by BIOS\n");
+ return false;
+ }
+
if (IS_MTL_MEDIA_STEP(gt->i915, STEP_A0, STEP_B0) &&
gt->type == GT_MEDIA) {
drm_notice(&i915->drm,
@@ -707,9 +729,14 @@ void intel_rc6_disable(struct intel_rc6 *rc6)
void intel_rc6_fini(struct intel_rc6 *rc6)
{
struct drm_i915_gem_object *pctx;
+ struct intel_uncore *uncore = rc6_to_uncore(rc6);
intel_rc6_disable(rc6);
+ /* We want the BIOS C6 state preserved across loads for MTL */
+ if (IS_METEORLAKE(rc6_to_i915(rc6)) && rc6->bios_state_captured)
+ set(uncore, GEN6_RC_STATE, rc6->bios_rc_state);
+
pctx = fetch_and_zero(&rc6->pctx);
if (pctx)
i915_gem_object_put(pctx);