diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_runtime_pm.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_runtime_pm.c | 151 |
1 files changed, 83 insertions, 68 deletions
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 6aeceab37000..79f00610860b 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c | |||
@@ -3997,7 +3997,7 @@ static void intel_power_domains_verify_state(struct drm_i915_private *dev_priv); | |||
3997 | 3997 | ||
3998 | /** | 3998 | /** |
3999 | * intel_power_domains_init_hw - initialize hardware power domain state | 3999 | * intel_power_domains_init_hw - initialize hardware power domain state |
4000 | * @dev_priv: i915 device instance | 4000 | * @i915: i915 device instance |
4001 | * @resume: Called from resume code paths or not | 4001 | * @resume: Called from resume code paths or not |
4002 | * | 4002 | * |
4003 | * This function initializes the hardware power domain state and enables all | 4003 | * This function initializes the hardware power domain state and enables all |
@@ -4011,30 +4011,31 @@ static void intel_power_domains_verify_state(struct drm_i915_private *dev_priv); | |||
4011 | * intel_power_domains_enable()) and must be paired with | 4011 | * intel_power_domains_enable()) and must be paired with |
4012 | * intel_power_domains_fini_hw(). | 4012 | * intel_power_domains_fini_hw(). |
4013 | */ | 4013 | */ |
4014 | void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume) | 4014 | void intel_power_domains_init_hw(struct drm_i915_private *i915, bool resume) |
4015 | { | 4015 | { |
4016 | struct i915_power_domains *power_domains = &dev_priv->power_domains; | 4016 | struct i915_power_domains *power_domains = &i915->power_domains; |
4017 | 4017 | ||
4018 | power_domains->initializing = true; | 4018 | power_domains->initializing = true; |
4019 | 4019 | ||
4020 | if (IS_ICELAKE(dev_priv)) { | 4020 | if (IS_ICELAKE(i915)) { |
4021 | icl_display_core_init(dev_priv, resume); | 4021 | icl_display_core_init(i915, resume); |
4022 | } else if (IS_CANNONLAKE(dev_priv)) { | 4022 | } else if (IS_CANNONLAKE(i915)) { |
4023 | cnl_display_core_init(dev_priv, resume); | 4023 | cnl_display_core_init(i915, resume); |
4024 | } else if (IS_GEN9_BC(dev_priv)) { | 4024 | } else if (IS_GEN9_BC(i915)) { |
4025 | skl_display_core_init(dev_priv, resume); | 4025 | skl_display_core_init(i915, resume); |
4026 | } else if (IS_GEN9_LP(dev_priv)) { | 4026 | } else if (IS_GEN9_LP(i915)) { |
4027 | bxt_display_core_init(dev_priv, resume); | 4027 | bxt_display_core_init(i915, resume); |
4028 | } else if (IS_CHERRYVIEW(dev_priv)) { | 4028 | } else if (IS_CHERRYVIEW(i915)) { |
4029 | mutex_lock(&power_domains->lock); | 4029 | mutex_lock(&power_domains->lock); |
4030 | chv_phy_control_init(dev_priv); | 4030 | chv_phy_control_init(i915); |
4031 | mutex_unlock(&power_domains->lock); | 4031 | mutex_unlock(&power_domains->lock); |
4032 | } else if (IS_VALLEYVIEW(dev_priv)) { | 4032 | } else if (IS_VALLEYVIEW(i915)) { |
4033 | mutex_lock(&power_domains->lock); | 4033 | mutex_lock(&power_domains->lock); |
4034 | vlv_cmnlane_wa(dev_priv); | 4034 | vlv_cmnlane_wa(i915); |
4035 | mutex_unlock(&power_domains->lock); | 4035 | mutex_unlock(&power_domains->lock); |
4036 | } else if (IS_IVYBRIDGE(dev_priv) || INTEL_GEN(dev_priv) >= 7) | 4036 | } else if (IS_IVYBRIDGE(i915) || INTEL_GEN(i915) >= 7) { |
4037 | intel_pch_reset_handshake(dev_priv, !HAS_PCH_NOP(dev_priv)); | 4037 | intel_pch_reset_handshake(i915, !HAS_PCH_NOP(i915)); |
4038 | } | ||
4038 | 4039 | ||
4039 | /* | 4040 | /* |
4040 | * Keep all power wells enabled for any dependent HW access during | 4041 | * Keep all power wells enabled for any dependent HW access during |
@@ -4042,18 +4043,20 @@ void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume) | |||
4042 | * resources powered until display HW readout is complete. We drop | 4043 | * resources powered until display HW readout is complete. We drop |
4043 | * this reference in intel_power_domains_enable(). | 4044 | * this reference in intel_power_domains_enable(). |
4044 | */ | 4045 | */ |
4045 | intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); | 4046 | power_domains->wakeref = |
4047 | intel_display_power_get(i915, POWER_DOMAIN_INIT); | ||
4048 | |||
4046 | /* Disable power support if the user asked so. */ | 4049 | /* Disable power support if the user asked so. */ |
4047 | if (!i915_modparams.disable_power_well) | 4050 | if (!i915_modparams.disable_power_well) |
4048 | intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); | 4051 | intel_display_power_get(i915, POWER_DOMAIN_INIT); |
4049 | intel_power_domains_sync_hw(dev_priv); | 4052 | intel_power_domains_sync_hw(i915); |
4050 | 4053 | ||
4051 | power_domains->initializing = false; | 4054 | power_domains->initializing = false; |
4052 | } | 4055 | } |
4053 | 4056 | ||
4054 | /** | 4057 | /** |
4055 | * intel_power_domains_fini_hw - deinitialize hw power domain state | 4058 | * intel_power_domains_fini_hw - deinitialize hw power domain state |
4056 | * @dev_priv: i915 device instance | 4059 | * @i915: i915 device instance |
4057 | * | 4060 | * |
4058 | * De-initializes the display power domain HW state. It also ensures that the | 4061 | * De-initializes the display power domain HW state. It also ensures that the |
4059 | * device stays powered up so that the driver can be reloaded. | 4062 | * device stays powered up so that the driver can be reloaded. |
@@ -4062,21 +4065,24 @@ void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume) | |||
4062 | * intel_power_domains_disable()) and must be paired with | 4065 | * intel_power_domains_disable()) and must be paired with |
4063 | * intel_power_domains_init_hw(). | 4066 | * intel_power_domains_init_hw(). |
4064 | */ | 4067 | */ |
4065 | void intel_power_domains_fini_hw(struct drm_i915_private *dev_priv) | 4068 | void intel_power_domains_fini_hw(struct drm_i915_private *i915) |
4066 | { | 4069 | { |
4067 | /* Keep the power well enabled, but cancel its rpm wakeref. */ | 4070 | intel_wakeref_t wakeref __maybe_unused = |
4068 | intel_runtime_pm_put_unchecked(dev_priv); | 4071 | fetch_and_zero(&i915->power_domains.wakeref); |
4069 | 4072 | ||
4070 | /* Remove the refcount we took to keep power well support disabled. */ | 4073 | /* Remove the refcount we took to keep power well support disabled. */ |
4071 | if (!i915_modparams.disable_power_well) | 4074 | if (!i915_modparams.disable_power_well) |
4072 | intel_display_power_put_unchecked(dev_priv, POWER_DOMAIN_INIT); | 4075 | intel_display_power_put_unchecked(i915, POWER_DOMAIN_INIT); |
4076 | |||
4077 | intel_power_domains_verify_state(i915); | ||
4073 | 4078 | ||
4074 | intel_power_domains_verify_state(dev_priv); | 4079 | /* Keep the power well enabled, but cancel its rpm wakeref. */ |
4080 | intel_runtime_pm_put(i915, wakeref); | ||
4075 | } | 4081 | } |
4076 | 4082 | ||
4077 | /** | 4083 | /** |
4078 | * intel_power_domains_enable - enable toggling of display power wells | 4084 | * intel_power_domains_enable - enable toggling of display power wells |
4079 | * @dev_priv: i915 device instance | 4085 | * @i915: i915 device instance |
4080 | * | 4086 | * |
4081 | * Enable the ondemand enabling/disabling of the display power wells. Note that | 4087 | * Enable the ondemand enabling/disabling of the display power wells. Note that |
4082 | * power wells not belonging to POWER_DOMAIN_INIT are allowed to be toggled | 4088 | * power wells not belonging to POWER_DOMAIN_INIT are allowed to be toggled |
@@ -4086,30 +4092,36 @@ void intel_power_domains_fini_hw(struct drm_i915_private *dev_priv) | |||
4086 | * of display HW readout (which will acquire the power references reflecting | 4092 | * of display HW readout (which will acquire the power references reflecting |
4087 | * the current HW state). | 4093 | * the current HW state). |
4088 | */ | 4094 | */ |
4089 | void intel_power_domains_enable(struct drm_i915_private *dev_priv) | 4095 | void intel_power_domains_enable(struct drm_i915_private *i915) |
4090 | { | 4096 | { |
4091 | intel_display_power_put_unchecked(dev_priv, POWER_DOMAIN_INIT); | 4097 | intel_wakeref_t wakeref __maybe_unused = |
4098 | fetch_and_zero(&i915->power_domains.wakeref); | ||
4092 | 4099 | ||
4093 | intel_power_domains_verify_state(dev_priv); | 4100 | intel_display_power_put(i915, POWER_DOMAIN_INIT, wakeref); |
4101 | intel_power_domains_verify_state(i915); | ||
4094 | } | 4102 | } |
4095 | 4103 | ||
4096 | /** | 4104 | /** |
4097 | * intel_power_domains_disable - disable toggling of display power wells | 4105 | * intel_power_domains_disable - disable toggling of display power wells |
4098 | * @dev_priv: i915 device instance | 4106 | * @i915: i915 device instance |
4099 | * | 4107 | * |
4100 | * Disable the ondemand enabling/disabling of the display power wells. See | 4108 | * Disable the ondemand enabling/disabling of the display power wells. See |
4101 | * intel_power_domains_enable() for which power wells this call controls. | 4109 | * intel_power_domains_enable() for which power wells this call controls. |
4102 | */ | 4110 | */ |
4103 | void intel_power_domains_disable(struct drm_i915_private *dev_priv) | 4111 | void intel_power_domains_disable(struct drm_i915_private *i915) |
4104 | { | 4112 | { |
4105 | intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); | 4113 | struct i915_power_domains *power_domains = &i915->power_domains; |
4106 | 4114 | ||
4107 | intel_power_domains_verify_state(dev_priv); | 4115 | WARN_ON(power_domains->wakeref); |
4116 | power_domains->wakeref = | ||
4117 | intel_display_power_get(i915, POWER_DOMAIN_INIT); | ||
4118 | |||
4119 | intel_power_domains_verify_state(i915); | ||
4108 | } | 4120 | } |
4109 | 4121 | ||
4110 | /** | 4122 | /** |
4111 | * intel_power_domains_suspend - suspend power domain state | 4123 | * intel_power_domains_suspend - suspend power domain state |
4112 | * @dev_priv: i915 device instance | 4124 | * @i915: i915 device instance |
4113 | * @suspend_mode: specifies the target suspend state (idle, mem, hibernation) | 4125 | * @suspend_mode: specifies the target suspend state (idle, mem, hibernation) |
4114 | * | 4126 | * |
4115 | * This function prepares the hardware power domain state before entering | 4127 | * This function prepares the hardware power domain state before entering |
@@ -4118,12 +4130,14 @@ void intel_power_domains_disable(struct drm_i915_private *dev_priv) | |||
4118 | * It must be called with power domains already disabled (after a call to | 4130 | * It must be called with power domains already disabled (after a call to |
4119 | * intel_power_domains_disable()) and paired with intel_power_domains_resume(). | 4131 | * intel_power_domains_disable()) and paired with intel_power_domains_resume(). |
4120 | */ | 4132 | */ |
4121 | void intel_power_domains_suspend(struct drm_i915_private *dev_priv, | 4133 | void intel_power_domains_suspend(struct drm_i915_private *i915, |
4122 | enum i915_drm_suspend_mode suspend_mode) | 4134 | enum i915_drm_suspend_mode suspend_mode) |
4123 | { | 4135 | { |
4124 | struct i915_power_domains *power_domains = &dev_priv->power_domains; | 4136 | struct i915_power_domains *power_domains = &i915->power_domains; |
4137 | intel_wakeref_t wakeref __maybe_unused = | ||
4138 | fetch_and_zero(&power_domains->wakeref); | ||
4125 | 4139 | ||
4126 | intel_display_power_put_unchecked(dev_priv, POWER_DOMAIN_INIT); | 4140 | intel_display_power_put(i915, POWER_DOMAIN_INIT, wakeref); |
4127 | 4141 | ||
4128 | /* | 4142 | /* |
4129 | * In case of suspend-to-idle (aka S0ix) on a DMC platform without DC9 | 4143 | * In case of suspend-to-idle (aka S0ix) on a DMC platform without DC9 |
@@ -4132,10 +4146,10 @@ void intel_power_domains_suspend(struct drm_i915_private *dev_priv, | |||
4132 | * resources as required and also enable deeper system power states | 4146 | * resources as required and also enable deeper system power states |
4133 | * that would be blocked if the firmware was inactive. | 4147 | * that would be blocked if the firmware was inactive. |
4134 | */ | 4148 | */ |
4135 | if (!(dev_priv->csr.allowed_dc_mask & DC_STATE_EN_DC9) && | 4149 | if (!(i915->csr.allowed_dc_mask & DC_STATE_EN_DC9) && |
4136 | suspend_mode == I915_DRM_SUSPEND_IDLE && | 4150 | suspend_mode == I915_DRM_SUSPEND_IDLE && |
4137 | dev_priv->csr.dmc_payload != NULL) { | 4151 | i915->csr.dmc_payload) { |
4138 | intel_power_domains_verify_state(dev_priv); | 4152 | intel_power_domains_verify_state(i915); |
4139 | return; | 4153 | return; |
4140 | } | 4154 | } |
4141 | 4155 | ||
@@ -4144,25 +4158,25 @@ void intel_power_domains_suspend(struct drm_i915_private *dev_priv, | |||
4144 | * power wells if power domains must be deinitialized for suspend. | 4158 | * power wells if power domains must be deinitialized for suspend. |
4145 | */ | 4159 | */ |
4146 | if (!i915_modparams.disable_power_well) { | 4160 | if (!i915_modparams.disable_power_well) { |
4147 | intel_display_power_put_unchecked(dev_priv, POWER_DOMAIN_INIT); | 4161 | intel_display_power_put_unchecked(i915, POWER_DOMAIN_INIT); |
4148 | intel_power_domains_verify_state(dev_priv); | 4162 | intel_power_domains_verify_state(i915); |
4149 | } | 4163 | } |
4150 | 4164 | ||
4151 | if (IS_ICELAKE(dev_priv)) | 4165 | if (IS_ICELAKE(i915)) |
4152 | icl_display_core_uninit(dev_priv); | 4166 | icl_display_core_uninit(i915); |
4153 | else if (IS_CANNONLAKE(dev_priv)) | 4167 | else if (IS_CANNONLAKE(i915)) |
4154 | cnl_display_core_uninit(dev_priv); | 4168 | cnl_display_core_uninit(i915); |
4155 | else if (IS_GEN9_BC(dev_priv)) | 4169 | else if (IS_GEN9_BC(i915)) |
4156 | skl_display_core_uninit(dev_priv); | 4170 | skl_display_core_uninit(i915); |
4157 | else if (IS_GEN9_LP(dev_priv)) | 4171 | else if (IS_GEN9_LP(i915)) |
4158 | bxt_display_core_uninit(dev_priv); | 4172 | bxt_display_core_uninit(i915); |
4159 | 4173 | ||
4160 | power_domains->display_core_suspended = true; | 4174 | power_domains->display_core_suspended = true; |
4161 | } | 4175 | } |
4162 | 4176 | ||
4163 | /** | 4177 | /** |
4164 | * intel_power_domains_resume - resume power domain state | 4178 | * intel_power_domains_resume - resume power domain state |
4165 | * @dev_priv: i915 device instance | 4179 | * @i915: i915 device instance |
4166 | * | 4180 | * |
4167 | * This function resume the hardware power domain state during system resume. | 4181 | * This function resume the hardware power domain state during system resume. |
4168 | * | 4182 | * |
@@ -4170,28 +4184,30 @@ void intel_power_domains_suspend(struct drm_i915_private *dev_priv, | |||
4170 | * intel_power_domains_enable()) and must be paired with | 4184 | * intel_power_domains_enable()) and must be paired with |
4171 | * intel_power_domains_suspend(). | 4185 | * intel_power_domains_suspend(). |
4172 | */ | 4186 | */ |
4173 | void intel_power_domains_resume(struct drm_i915_private *dev_priv) | 4187 | void intel_power_domains_resume(struct drm_i915_private *i915) |
4174 | { | 4188 | { |
4175 | struct i915_power_domains *power_domains = &dev_priv->power_domains; | 4189 | struct i915_power_domains *power_domains = &i915->power_domains; |
4176 | 4190 | ||
4177 | if (power_domains->display_core_suspended) { | 4191 | if (power_domains->display_core_suspended) { |
4178 | intel_power_domains_init_hw(dev_priv, true); | 4192 | intel_power_domains_init_hw(i915, true); |
4179 | power_domains->display_core_suspended = false; | 4193 | power_domains->display_core_suspended = false; |
4180 | } else { | 4194 | } else { |
4181 | intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); | 4195 | WARN_ON(power_domains->wakeref); |
4196 | power_domains->wakeref = | ||
4197 | intel_display_power_get(i915, POWER_DOMAIN_INIT); | ||
4182 | } | 4198 | } |
4183 | 4199 | ||
4184 | intel_power_domains_verify_state(dev_priv); | 4200 | intel_power_domains_verify_state(i915); |
4185 | } | 4201 | } |
4186 | 4202 | ||
4187 | #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) | 4203 | #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) |
4188 | 4204 | ||
4189 | static void intel_power_domains_dump_info(struct drm_i915_private *dev_priv) | 4205 | static void intel_power_domains_dump_info(struct drm_i915_private *i915) |
4190 | { | 4206 | { |
4191 | struct i915_power_domains *power_domains = &dev_priv->power_domains; | 4207 | struct i915_power_domains *power_domains = &i915->power_domains; |
4192 | struct i915_power_well *power_well; | 4208 | struct i915_power_well *power_well; |
4193 | 4209 | ||
4194 | for_each_power_well(dev_priv, power_well) { | 4210 | for_each_power_well(i915, power_well) { |
4195 | enum intel_display_power_domain domain; | 4211 | enum intel_display_power_domain domain; |
4196 | 4212 | ||
4197 | DRM_DEBUG_DRIVER("%-25s %d\n", | 4213 | DRM_DEBUG_DRIVER("%-25s %d\n", |
@@ -4206,7 +4222,7 @@ static void intel_power_domains_dump_info(struct drm_i915_private *dev_priv) | |||
4206 | 4222 | ||
4207 | /** | 4223 | /** |
4208 | * intel_power_domains_verify_state - verify the HW/SW state for all power wells | 4224 | * intel_power_domains_verify_state - verify the HW/SW state for all power wells |
4209 | * @dev_priv: i915 device instance | 4225 | * @i915: i915 device instance |
4210 | * | 4226 | * |
4211 | * Verify if the reference count of each power well matches its HW enabled | 4227 | * Verify if the reference count of each power well matches its HW enabled |
4212 | * state and the total refcount of the domains it belongs to. This must be | 4228 | * state and the total refcount of the domains it belongs to. This must be |
@@ -4214,22 +4230,21 @@ static void intel_power_domains_dump_info(struct drm_i915_private *dev_priv) | |||
4214 | * acquiring reference counts for any power wells in use and disabling the | 4230 | * acquiring reference counts for any power wells in use and disabling the |
4215 | * ones left on by BIOS but not required by any active output. | 4231 | * ones left on by BIOS but not required by any active output. |
4216 | */ | 4232 | */ |
4217 | static void intel_power_domains_verify_state(struct drm_i915_private *dev_priv) | 4233 | static void intel_power_domains_verify_state(struct drm_i915_private *i915) |
4218 | { | 4234 | { |
4219 | struct i915_power_domains *power_domains = &dev_priv->power_domains; | 4235 | struct i915_power_domains *power_domains = &i915->power_domains; |
4220 | struct i915_power_well *power_well; | 4236 | struct i915_power_well *power_well; |
4221 | bool dump_domain_info; | 4237 | bool dump_domain_info; |
4222 | 4238 | ||
4223 | mutex_lock(&power_domains->lock); | 4239 | mutex_lock(&power_domains->lock); |
4224 | 4240 | ||
4225 | dump_domain_info = false; | 4241 | dump_domain_info = false; |
4226 | for_each_power_well(dev_priv, power_well) { | 4242 | for_each_power_well(i915, power_well) { |
4227 | enum intel_display_power_domain domain; | 4243 | enum intel_display_power_domain domain; |
4228 | int domains_count; | 4244 | int domains_count; |
4229 | bool enabled; | 4245 | bool enabled; |
4230 | 4246 | ||
4231 | enabled = power_well->desc->ops->is_enabled(dev_priv, | 4247 | enabled = power_well->desc->ops->is_enabled(i915, power_well); |
4232 | power_well); | ||
4233 | if ((power_well->count || power_well->desc->always_on) != | 4248 | if ((power_well->count || power_well->desc->always_on) != |
4234 | enabled) | 4249 | enabled) |
4235 | DRM_ERROR("power well %s state mismatch (refcount %d/enabled %d)", | 4250 | DRM_ERROR("power well %s state mismatch (refcount %d/enabled %d)", |
@@ -4253,7 +4268,7 @@ static void intel_power_domains_verify_state(struct drm_i915_private *dev_priv) | |||
4253 | static bool dumped; | 4268 | static bool dumped; |
4254 | 4269 | ||
4255 | if (!dumped) { | 4270 | if (!dumped) { |
4256 | intel_power_domains_dump_info(dev_priv); | 4271 | intel_power_domains_dump_info(i915); |
4257 | dumped = true; | 4272 | dumped = true; |
4258 | } | 4273 | } |
4259 | } | 4274 | } |
@@ -4263,7 +4278,7 @@ static void intel_power_domains_verify_state(struct drm_i915_private *dev_priv) | |||
4263 | 4278 | ||
4264 | #else | 4279 | #else |
4265 | 4280 | ||
4266 | static void intel_power_domains_verify_state(struct drm_i915_private *dev_priv) | 4281 | static void intel_power_domains_verify_state(struct drm_i915_private *i915) |
4267 | { | 4282 | { |
4268 | } | 4283 | } |
4269 | 4284 | ||