@@ -1760,8 +1760,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);
@@ -144,11 +144,11 @@ MODULE_PARM_DESC(fastboot, "Try to skip unnecessary mode sets at boot time "
int i915_enable_pc8 __read_mostly = 1;
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_PARM_DESC(enable_pc8, "Ignored. Deprecated by runtime PM support.");
-int i915_pc8_timeout __read_mostly = 5000;
+int i915_pc8_timeout __read_mostly = 0;
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_PARM_DESC(pc8_timeout, "Ignored. Deprecated by runtime PM autosuspend delay.");
bool i915_prefault_disable __read_mostly;
module_param_named(prefault_disable, i915_prefault_disable, bool, 0600);
@@ -921,12 +921,16 @@ 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);
dev_priv->pm.suspended = true;
intel_opregion_notify_adapter(dev, PCI_D3cold);
+ DRM_DEBUG_KMS("Device suspended\n");
return 0;
}
@@ -943,6 +947,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;
}
@@ -1256,6 +1256,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
@@ -1311,7 +1315,6 @@ struct i915_package_c8 {
bool enabled;
int disable_count;
struct mutex lock;
- struct delayed_work enable_work;
struct {
uint32_t deimr;
@@ -1915,8 +1918,6 @@ extern unsigned int i915_preliminary_hw_support __read_mostly;
extern int i915_disable_power_well __read_mostly;
extern int i915_enable_ips __read_mostly;
extern bool i915_fastboot __read_mostly;
-extern int i915_enable_pc8 __read_mostly;
-extern int i915_pc8_timeout __read_mostly;
extern bool i915_prefault_disable __read_mostly;
extern int i915_suspend(struct drm_device *dev, pm_message_t state);
@@ -6601,7 +6601,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;
@@ -6635,14 +6635,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;
@@ -6658,22 +6660,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));
@@ -6684,15 +6670,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);
@@ -6715,8 +6702,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);
@@ -6725,14 +6710,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)
@@ -6790,9 +6768,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);
@@ -694,7 +694,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,
@@ -5785,7 +5785,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 = 2; /* requirements_met + gpu_idle */
- 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);
}