Commit be3d26b0 authored by Paulo Zanoni's avatar Paulo Zanoni Committed by Daniel Vetter

drm/i915: get a PC8 reference when enabling the power well

In the current code, at haswell_modeset_global_resources, first we
decide if we want to enable/disable the power well, then we decide if
we want to enable/disable PC8. On the case where we're enabling PC8
this works fine, but on the case where we disable PC8 due to a non-eDP
monitor being enabled, we first enable the power well and then disable
PC8. Although wrong, this doesn't seem to be causing any problems now,
and we don't even see anything in dmesg. But the patches for runtime
D3 turn this problem into a real bug, so we need to fix it.

This fixes the "modeset-non-lpsp" subtest from the "pm_pc8" test from
intel-gpu-tools.

v2: - Rebase (i915_disable_power_well).
v3: - More reabase.
v4: - Rebase on top of -fixes instead of -nightly.

This is commit d62292c8 in -next, but
we need it in -fixes to address Dave's report.
Signed-off-by: default avatarPaulo Zanoni <paulo.r.zanoni@intel.com>
Reviewed-by: default avatarRodrigo Vivi <rodrigo.vivi@gmail.com>
Reported-by: default avatarDave Jones <davej@redhat.com>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 96b40268
...@@ -5688,6 +5688,8 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable) ...@@ -5688,6 +5688,8 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable)
unsigned long irqflags; unsigned long irqflags;
uint32_t tmp; uint32_t tmp;
WARN_ON(dev_priv->pc8.enabled);
tmp = I915_READ(HSW_PWR_WELL_DRIVER); tmp = I915_READ(HSW_PWR_WELL_DRIVER);
is_enabled = tmp & HSW_PWR_WELL_STATE_ENABLED; is_enabled = tmp & HSW_PWR_WELL_STATE_ENABLED;
enable_requested = tmp & HSW_PWR_WELL_ENABLE_REQUEST; enable_requested = tmp & HSW_PWR_WELL_ENABLE_REQUEST;
...@@ -5747,16 +5749,24 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable) ...@@ -5747,16 +5749,24 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable)
static void __intel_power_well_get(struct drm_device *dev, static void __intel_power_well_get(struct drm_device *dev,
struct i915_power_well *power_well) struct i915_power_well *power_well)
{ {
if (!power_well->count++) struct drm_i915_private *dev_priv = dev->dev_private;
if (!power_well->count++) {
hsw_disable_package_c8(dev_priv);
__intel_set_power_well(dev, true); __intel_set_power_well(dev, true);
}
} }
static void __intel_power_well_put(struct drm_device *dev, static void __intel_power_well_put(struct drm_device *dev,
struct i915_power_well *power_well) struct i915_power_well *power_well)
{ {
struct drm_i915_private *dev_priv = dev->dev_private;
WARN_ON(!power_well->count); WARN_ON(!power_well->count);
if (!--power_well->count && i915_disable_power_well) if (!--power_well->count && i915_disable_power_well) {
__intel_set_power_well(dev, false); __intel_set_power_well(dev, false);
hsw_enable_package_c8(dev_priv);
}
} }
void intel_display_power_get(struct drm_device *dev, void intel_display_power_get(struct drm_device *dev,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment