@@ -1818,8 +1818,6 @@ int i915_driver_unload(struct drm_device *dev)
cancel_work_sync(&dev_priv->gpu_error.work);
i915_destroy_error_state(dev);
- cancel_delayed_work_sync(&dev_priv->pc8.enable_work);
-
if (dev->pdev->msi_enabled)
pci_disable_msi(dev->pdev);
@@ -850,6 +850,9 @@ static int i915_runtime_suspend(struct device *device)
DRM_DEBUG_KMS("Suspending device\n");
+ if (HAS_PC8(dev))
+ __hsw_do_enable_pc8(dev_priv);
+
i915_gem_release_all_mmaps(dev_priv);
del_timer_sync(&dev_priv->gpu_error.hangcheck_timer);
@@ -864,6 +867,7 @@ static int i915_runtime_suspend(struct device *device)
*/
intel_opregion_notify_adapter(dev, PCI_D1);
+ DRM_DEBUG_KMS("Device suspended\n");
return 0;
}
@@ -880,6 +884,10 @@ static int i915_runtime_resume(struct device *device)
intel_opregion_notify_adapter(dev, PCI_D0);
dev_priv->pm.suspended = false;
+ if (HAS_PC8(dev))
+ __hsw_do_disable_pc8(dev_priv);
+
+ DRM_DEBUG_KMS("Device resumed\n");
return 0;
}
@@ -1299,6 +1299,10 @@ struct ilk_wm_values {
/*
* This struct tracks the state needed for the Package C8+ feature.
*
+ * TODO: we're merging the Package C8+ feature with the runtime PM support. To
+ * avoid having to update the documentation at each patch of the series, we'll
+ * do a final update at the end.
+ *
* Package states C8 and deeper are really deep PC states that can only be
* reached when all the devices on the system allow it, so even if the graphics
* device allows PC8+, it doesn't mean the system will actually get to these
@@ -1352,7 +1356,6 @@ struct i915_package_c8 {
bool enabled;
int disable_count;
struct mutex lock;
- struct delayed_work enable_work;
struct {
uint32_t deimr;
@@ -1968,8 +1971,6 @@ struct i915_params {
unsigned int preliminary_hw_support;
int disable_power_well;
int enable_ips;
- int enable_pc8;
- int pc8_timeout;
int invert_brightness;
/* leave bools at the end to not create holes */
bool enable_hangcheck;
@@ -42,8 +42,6 @@ struct i915_params i915 __read_mostly = {
.disable_power_well = 1,
.enable_ips = 1,
.fastboot = 0,
- .enable_pc8 = 1,
- .pc8_timeout = 5000,
.prefault_disable = 0,
.reset = true,
.invert_brightness = 0,
@@ -134,14 +132,6 @@ module_param_named(fastboot, i915.fastboot, bool, 0600);
MODULE_PARM_DESC(fastboot,
"Try to skip unnecessary mode sets at boot time (default: false)");
-module_param_named(enable_pc8, i915.enable_pc8, int, 0600);
-MODULE_PARM_DESC(enable_pc8,
- "Enable support for low power package C states (PC8+) (default: true)");
-
-module_param_named(pc8_timeout, i915.pc8_timeout, int, 0600);
-MODULE_PARM_DESC(pc8_timeout,
- "Number of msecs of idleness required to enter PC8+ (default: 5000)");
-
module_param_named(prefault_disable, i915.prefault_disable, bool, 0600);
MODULE_PARM_DESC(prefault_disable,
"Disable page prefaulting for pread/pwrite/reloc (default:false). "
@@ -6614,7 +6614,7 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
/* Make sure we're not on PC8 state before disabling PC8, otherwise
* we'll hang the machine! */
- gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
+ gen6_gt_force_wake_get_no_rpm(dev_priv, FORCEWAKE_ALL);
if (val & LCPLL_POWER_DOWN_ALLOW) {
val &= ~LCPLL_POWER_DOWN_ALLOW;
@@ -6648,14 +6648,16 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
DRM_ERROR("Switching back to LCPLL failed\n");
}
- gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
+ gen6_gt_force_wake_put_no_rpm(dev_priv, FORCEWAKE_ALL);
}
-static void __hsw_do_enable_pc8(struct drm_i915_private *dev_priv)
+void __hsw_do_enable_pc8(struct drm_i915_private *dev_priv)
{
struct drm_device *dev = dev_priv->dev;
uint32_t val;
+ WARN_ON(!HAS_PC8(dev));
+
DRM_DEBUG_KMS("Enabling package C8+\n");
dev_priv->pc8.enabled = true;
@@ -6671,22 +6673,6 @@ static void __hsw_do_enable_pc8(struct drm_i915_private *dev_priv)
hsw_disable_lcpll(dev_priv, true, true);
}
-void hsw_enable_pc8_work(struct work_struct *__work)
-{
- struct drm_i915_private *dev_priv =
- container_of(to_delayed_work(__work), struct drm_i915_private,
- pc8.enable_work);
- struct drm_device *dev = dev_priv->dev;
-
- WARN_ON(!HAS_PC8(dev));
-
- if (dev_priv->pc8.enabled)
- return;
-
- __hsw_do_enable_pc8(dev_priv);
- intel_runtime_pm_put(dev_priv);
-}
-
static void __hsw_enable_package_c8(struct drm_i915_private *dev_priv)
{
WARN_ON(!mutex_is_locked(&dev_priv->pc8.lock));
@@ -6697,15 +6683,16 @@ static void __hsw_enable_package_c8(struct drm_i915_private *dev_priv)
if (dev_priv->pc8.disable_count != 0)
return;
- schedule_delayed_work(&dev_priv->pc8.enable_work,
- msecs_to_jiffies(i915.pc8_timeout));
+ intel_runtime_pm_put(dev_priv);
}
-static void __hsw_do_disable_package_c8(struct drm_i915_private *dev_priv)
+void __hsw_do_disable_pc8(struct drm_i915_private *dev_priv)
{
struct drm_device *dev = dev_priv->dev;
uint32_t val;
+ WARN_ON(!HAS_PC8(dev));
+
DRM_DEBUG_KMS("Disabling package C8+\n");
hsw_restore_lcpll(dev_priv);
@@ -6728,8 +6715,6 @@ static void __hsw_do_disable_package_c8(struct drm_i915_private *dev_priv)
static void __hsw_disable_package_c8(struct drm_i915_private *dev_priv)
{
- struct drm_device *dev = dev_priv->dev;
-
WARN_ON(!mutex_is_locked(&dev_priv->pc8.lock));
WARN(dev_priv->pc8.disable_count < 0,
"pc8.disable_count: %d\n", dev_priv->pc8.disable_count);
@@ -6738,14 +6723,7 @@ static void __hsw_disable_package_c8(struct drm_i915_private *dev_priv)
if (dev_priv->pc8.disable_count != 1)
return;
- WARN_ON(!HAS_PC8(dev));
-
- cancel_delayed_work_sync(&dev_priv->pc8.enable_work);
- if (!dev_priv->pc8.enabled)
- return;
-
intel_runtime_pm_get(dev_priv);
- __hsw_do_disable_package_c8(dev_priv);
}
void hsw_enable_package_c8(struct drm_i915_private *dev_priv)
@@ -6803,9 +6781,6 @@ static void hsw_update_package_c8(struct drm_device *dev)
if (!HAS_PC8(dev_priv->dev))
return;
- if (!i915.enable_pc8)
- return;
-
mutex_lock(&dev_priv->pc8.lock);
allow = hsw_can_enable_package_c8(dev_priv);
@@ -720,7 +720,8 @@ unsigned long intel_gen4_compute_page_offset(int *x, int *y,
unsigned int bpp,
unsigned int pitch);
void intel_display_handle_reset(struct drm_device *dev);
-void hsw_enable_pc8_work(struct work_struct *__work);
+void __hsw_do_enable_pc8(struct drm_i915_private *dev_priv);
+void __hsw_do_disable_pc8(struct drm_i915_private *dev_priv);
void hsw_enable_package_c8(struct drm_i915_private *dev_priv);
void hsw_disable_package_c8(struct drm_i915_private *dev_priv);
void intel_dp_get_m_n(struct intel_crtc *crtc,
@@ -5789,7 +5789,6 @@ void intel_pm_setup(struct drm_device *dev)
dev_priv->pc8.irqs_disabled = false;
dev_priv->pc8.enabled = false;
dev_priv->pc8.disable_count = 1; /* requirements_met */
- INIT_DELAYED_WORK(&dev_priv->pc8.enable_work, hsw_enable_pc8_work);
INIT_DELAYED_WORK(&dev_priv->rps.delayed_resume_work,
intel_gen6_powersave_work);
}