diff options
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 54 |
3 files changed, 43 insertions, 23 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index f3ac1f45e154..f1e651703764 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -2502,7 +2502,7 @@ static int intel_runtime_suspend(struct device *kdev) | |||
2502 | struct drm_i915_private *dev_priv = to_i915(dev); | 2502 | struct drm_i915_private *dev_priv = to_i915(dev); |
2503 | int ret; | 2503 | int ret; |
2504 | 2504 | ||
2505 | if (WARN_ON_ONCE(!(dev_priv->gt_pm.rps.enabled && intel_rc6_enabled()))) | 2505 | if (WARN_ON_ONCE(!(dev_priv->gt_pm.rc6.enabled && intel_rc6_enabled()))) |
2506 | return -ENODEV; | 2506 | return -ENODEV; |
2507 | 2507 | ||
2508 | if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev_priv))) | 2508 | if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev_priv))) |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 521348ee7242..6bbc4b83aa0a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -1365,8 +1365,18 @@ struct intel_rps { | |||
1365 | struct intel_rps_ei ei; | 1365 | struct intel_rps_ei ei; |
1366 | }; | 1366 | }; |
1367 | 1367 | ||
1368 | struct intel_rc6 { | ||
1369 | bool enabled; | ||
1370 | }; | ||
1371 | |||
1372 | struct intel_llc_pstate { | ||
1373 | bool enabled; | ||
1374 | }; | ||
1375 | |||
1368 | struct intel_gen6_power_mgmt { | 1376 | struct intel_gen6_power_mgmt { |
1369 | struct intel_rps rps; | 1377 | struct intel_rps rps; |
1378 | struct intel_rc6 rc6; | ||
1379 | struct intel_llc_pstate llc_pstate; | ||
1370 | struct delayed_work autoenable_work; | 1380 | struct delayed_work autoenable_work; |
1371 | }; | 1381 | }; |
1372 | 1382 | ||
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index a4d431d3980a..2fcff9788b6f 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -7964,7 +7964,8 @@ void intel_suspend_gt_powersave(struct drm_i915_private *dev_priv) | |||
7964 | 7964 | ||
7965 | void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv) | 7965 | void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv) |
7966 | { | 7966 | { |
7967 | dev_priv->gt_pm.rps.enabled = true; /* force disabling */ | 7967 | dev_priv->gt_pm.rps.enabled = true; /* force RPS disabling */ |
7968 | dev_priv->gt_pm.rc6.enabled = true; /* force RC6 disabling */ | ||
7968 | intel_disable_gt_powersave(dev_priv); | 7969 | intel_disable_gt_powersave(dev_priv); |
7969 | 7970 | ||
7970 | gen6_reset_rps_interrupts(dev_priv); | 7971 | gen6_reset_rps_interrupts(dev_priv); |
@@ -7974,13 +7975,21 @@ static inline void intel_disable_llc_pstate(struct drm_i915_private *i915) | |||
7974 | { | 7975 | { |
7975 | lockdep_assert_held(&i915->pcu_lock); | 7976 | lockdep_assert_held(&i915->pcu_lock); |
7976 | 7977 | ||
7978 | if (!i915->gt_pm.llc_pstate.enabled) | ||
7979 | return; | ||
7980 | |||
7977 | /* Currently there is no HW configuration to be done to disable. */ | 7981 | /* Currently there is no HW configuration to be done to disable. */ |
7982 | |||
7983 | i915->gt_pm.llc_pstate.enabled = false; | ||
7978 | } | 7984 | } |
7979 | 7985 | ||
7980 | static void intel_disable_rc6(struct drm_i915_private *dev_priv) | 7986 | static void intel_disable_rc6(struct drm_i915_private *dev_priv) |
7981 | { | 7987 | { |
7982 | lockdep_assert_held(&dev_priv->pcu_lock); | 7988 | lockdep_assert_held(&dev_priv->pcu_lock); |
7983 | 7989 | ||
7990 | if (!dev_priv->gt_pm.rc6.enabled) | ||
7991 | return; | ||
7992 | |||
7984 | if (INTEL_GEN(dev_priv) >= 9) | 7993 | if (INTEL_GEN(dev_priv) >= 9) |
7985 | gen9_disable_rc6(dev_priv); | 7994 | gen9_disable_rc6(dev_priv); |
7986 | else if (IS_CHERRYVIEW(dev_priv)) | 7995 | else if (IS_CHERRYVIEW(dev_priv)) |
@@ -7989,12 +7998,17 @@ static void intel_disable_rc6(struct drm_i915_private *dev_priv) | |||
7989 | valleyview_disable_rc6(dev_priv); | 7998 | valleyview_disable_rc6(dev_priv); |
7990 | else if (INTEL_GEN(dev_priv) >= 6) | 7999 | else if (INTEL_GEN(dev_priv) >= 6) |
7991 | gen6_disable_rc6(dev_priv); | 8000 | gen6_disable_rc6(dev_priv); |
8001 | |||
8002 | dev_priv->gt_pm.rc6.enabled = false; | ||
7992 | } | 8003 | } |
7993 | 8004 | ||
7994 | static void intel_disable_rps(struct drm_i915_private *dev_priv) | 8005 | static void intel_disable_rps(struct drm_i915_private *dev_priv) |
7995 | { | 8006 | { |
7996 | lockdep_assert_held(&dev_priv->pcu_lock); | 8007 | lockdep_assert_held(&dev_priv->pcu_lock); |
7997 | 8008 | ||
8009 | if (!dev_priv->gt_pm.rps.enabled) | ||
8010 | return; | ||
8011 | |||
7998 | if (INTEL_GEN(dev_priv) >= 9) | 8012 | if (INTEL_GEN(dev_priv) >= 9) |
7999 | gen9_disable_rps(dev_priv); | 8013 | gen9_disable_rps(dev_priv); |
8000 | else if (IS_CHERRYVIEW(dev_priv)) | 8014 | else if (IS_CHERRYVIEW(dev_priv)) |
@@ -8005,15 +8019,12 @@ static void intel_disable_rps(struct drm_i915_private *dev_priv) | |||
8005 | gen6_disable_rps(dev_priv); | 8019 | gen6_disable_rps(dev_priv); |
8006 | else if (IS_IRONLAKE_M(dev_priv)) | 8020 | else if (IS_IRONLAKE_M(dev_priv)) |
8007 | ironlake_disable_drps(dev_priv); | 8021 | ironlake_disable_drps(dev_priv); |
8022 | |||
8023 | dev_priv->gt_pm.rps.enabled = false; | ||
8008 | } | 8024 | } |
8009 | 8025 | ||
8010 | void intel_disable_gt_powersave(struct drm_i915_private *dev_priv) | 8026 | void intel_disable_gt_powersave(struct drm_i915_private *dev_priv) |
8011 | { | 8027 | { |
8012 | struct intel_rps *rps = &dev_priv->gt_pm.rps; | ||
8013 | |||
8014 | if (!READ_ONCE(rps->enabled)) | ||
8015 | return; | ||
8016 | |||
8017 | mutex_lock(&dev_priv->pcu_lock); | 8028 | mutex_lock(&dev_priv->pcu_lock); |
8018 | 8029 | ||
8019 | intel_disable_rc6(dev_priv); | 8030 | intel_disable_rc6(dev_priv); |
@@ -8021,7 +8032,6 @@ void intel_disable_gt_powersave(struct drm_i915_private *dev_priv) | |||
8021 | if (HAS_LLC(dev_priv)) | 8032 | if (HAS_LLC(dev_priv)) |
8022 | intel_disable_llc_pstate(dev_priv); | 8033 | intel_disable_llc_pstate(dev_priv); |
8023 | 8034 | ||
8024 | rps->enabled = false; | ||
8025 | mutex_unlock(&dev_priv->pcu_lock); | 8035 | mutex_unlock(&dev_priv->pcu_lock); |
8026 | } | 8036 | } |
8027 | 8037 | ||
@@ -8029,13 +8039,21 @@ static inline void intel_enable_llc_pstate(struct drm_i915_private *i915) | |||
8029 | { | 8039 | { |
8030 | lockdep_assert_held(&i915->pcu_lock); | 8040 | lockdep_assert_held(&i915->pcu_lock); |
8031 | 8041 | ||
8042 | if (i915->gt_pm.llc_pstate.enabled) | ||
8043 | return; | ||
8044 | |||
8032 | gen6_update_ring_freq(i915); | 8045 | gen6_update_ring_freq(i915); |
8046 | |||
8047 | i915->gt_pm.llc_pstate.enabled = true; | ||
8033 | } | 8048 | } |
8034 | 8049 | ||
8035 | static void intel_enable_rc6(struct drm_i915_private *dev_priv) | 8050 | static void intel_enable_rc6(struct drm_i915_private *dev_priv) |
8036 | { | 8051 | { |
8037 | lockdep_assert_held(&dev_priv->pcu_lock); | 8052 | lockdep_assert_held(&dev_priv->pcu_lock); |
8038 | 8053 | ||
8054 | if (dev_priv->gt_pm.rc6.enabled) | ||
8055 | return; | ||
8056 | |||
8039 | if (IS_CHERRYVIEW(dev_priv)) | 8057 | if (IS_CHERRYVIEW(dev_priv)) |
8040 | cherryview_enable_rc6(dev_priv); | 8058 | cherryview_enable_rc6(dev_priv); |
8041 | else if (IS_VALLEYVIEW(dev_priv)) | 8059 | else if (IS_VALLEYVIEW(dev_priv)) |
@@ -8046,6 +8064,8 @@ static void intel_enable_rc6(struct drm_i915_private *dev_priv) | |||
8046 | gen8_enable_rc6(dev_priv); | 8064 | gen8_enable_rc6(dev_priv); |
8047 | else if (INTEL_GEN(dev_priv) >= 6) | 8065 | else if (INTEL_GEN(dev_priv) >= 6) |
8048 | gen6_enable_rc6(dev_priv); | 8066 | gen6_enable_rc6(dev_priv); |
8067 | |||
8068 | dev_priv->gt_pm.rc6.enabled = true; | ||
8049 | } | 8069 | } |
8050 | 8070 | ||
8051 | static void intel_enable_rps(struct drm_i915_private *dev_priv) | 8071 | static void intel_enable_rps(struct drm_i915_private *dev_priv) |
@@ -8054,6 +8074,9 @@ static void intel_enable_rps(struct drm_i915_private *dev_priv) | |||
8054 | 8074 | ||
8055 | lockdep_assert_held(&dev_priv->pcu_lock); | 8075 | lockdep_assert_held(&dev_priv->pcu_lock); |
8056 | 8076 | ||
8077 | if (rps->enabled) | ||
8078 | return; | ||
8079 | |||
8057 | if (IS_CHERRYVIEW(dev_priv)) { | 8080 | if (IS_CHERRYVIEW(dev_priv)) { |
8058 | cherryview_enable_rps(dev_priv); | 8081 | cherryview_enable_rps(dev_priv); |
8059 | } else if (IS_VALLEYVIEW(dev_priv)) { | 8082 | } else if (IS_VALLEYVIEW(dev_priv)) { |
@@ -8074,18 +8097,12 @@ static void intel_enable_rps(struct drm_i915_private *dev_priv) | |||
8074 | 8097 | ||
8075 | WARN_ON(rps->efficient_freq < rps->min_freq); | 8098 | WARN_ON(rps->efficient_freq < rps->min_freq); |
8076 | WARN_ON(rps->efficient_freq > rps->max_freq); | 8099 | WARN_ON(rps->efficient_freq > rps->max_freq); |
8100 | |||
8101 | rps->enabled = true; | ||
8077 | } | 8102 | } |
8078 | 8103 | ||
8079 | void intel_enable_gt_powersave(struct drm_i915_private *dev_priv) | 8104 | void intel_enable_gt_powersave(struct drm_i915_private *dev_priv) |
8080 | { | 8105 | { |
8081 | struct intel_rps *rps = &dev_priv->gt_pm.rps; | ||
8082 | |||
8083 | /* We shouldn't be disabling as we submit, so this should be less | ||
8084 | * racy than it appears! | ||
8085 | */ | ||
8086 | if (READ_ONCE(rps->enabled)) | ||
8087 | return; | ||
8088 | |||
8089 | /* Powersaving is controlled by the host when inside a VM */ | 8106 | /* Powersaving is controlled by the host when inside a VM */ |
8090 | if (intel_vgpu_active(dev_priv)) | 8107 | if (intel_vgpu_active(dev_priv)) |
8091 | return; | 8108 | return; |
@@ -8097,7 +8114,6 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv) | |||
8097 | if (HAS_LLC(dev_priv)) | 8114 | if (HAS_LLC(dev_priv)) |
8098 | intel_enable_llc_pstate(dev_priv); | 8115 | intel_enable_llc_pstate(dev_priv); |
8099 | 8116 | ||
8100 | rps->enabled = true; | ||
8101 | mutex_unlock(&dev_priv->pcu_lock); | 8117 | mutex_unlock(&dev_priv->pcu_lock); |
8102 | } | 8118 | } |
8103 | 8119 | ||
@@ -8110,9 +8126,6 @@ static void __intel_autoenable_gt_powersave(struct work_struct *work) | |||
8110 | struct intel_engine_cs *rcs; | 8126 | struct intel_engine_cs *rcs; |
8111 | struct drm_i915_gem_request *req; | 8127 | struct drm_i915_gem_request *req; |
8112 | 8128 | ||
8113 | if (READ_ONCE(dev_priv->gt_pm.rps.enabled)) | ||
8114 | goto out; | ||
8115 | |||
8116 | rcs = dev_priv->engine[RCS]; | 8129 | rcs = dev_priv->engine[RCS]; |
8117 | if (rcs->last_retired_context) | 8130 | if (rcs->last_retired_context) |
8118 | goto out; | 8131 | goto out; |
@@ -8140,9 +8153,6 @@ out: | |||
8140 | 8153 | ||
8141 | void intel_autoenable_gt_powersave(struct drm_i915_private *dev_priv) | 8154 | void intel_autoenable_gt_powersave(struct drm_i915_private *dev_priv) |
8142 | { | 8155 | { |
8143 | if (READ_ONCE(dev_priv->gt_pm.rps.enabled)) | ||
8144 | return; | ||
8145 | |||
8146 | if (IS_IRONLAKE_M(dev_priv)) { | 8156 | if (IS_IRONLAKE_M(dev_priv)) { |
8147 | ironlake_enable_drps(dev_priv); | 8157 | ironlake_enable_drps(dev_priv); |
8148 | intel_init_emon(dev_priv); | 8158 | intel_init_emon(dev_priv); |