diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pm.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 6e0d5e075b15..26c29c173221 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -5685,8 +5685,11 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable) | |||
5685 | { | 5685 | { |
5686 | struct drm_i915_private *dev_priv = dev->dev_private; | 5686 | struct drm_i915_private *dev_priv = dev->dev_private; |
5687 | bool is_enabled, enable_requested; | 5687 | bool is_enabled, enable_requested; |
5688 | unsigned long irqflags; | ||
5688 | uint32_t tmp; | 5689 | uint32_t tmp; |
5689 | 5690 | ||
5691 | WARN_ON(dev_priv->pc8.enabled); | ||
5692 | |||
5690 | tmp = I915_READ(HSW_PWR_WELL_DRIVER); | 5693 | tmp = I915_READ(HSW_PWR_WELL_DRIVER); |
5691 | is_enabled = tmp & HSW_PWR_WELL_STATE_ENABLED; | 5694 | is_enabled = tmp & HSW_PWR_WELL_STATE_ENABLED; |
5692 | enable_requested = tmp & HSW_PWR_WELL_ENABLE_REQUEST; | 5695 | enable_requested = tmp & HSW_PWR_WELL_ENABLE_REQUEST; |
@@ -5702,9 +5705,24 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable) | |||
5702 | HSW_PWR_WELL_STATE_ENABLED), 20)) | 5705 | HSW_PWR_WELL_STATE_ENABLED), 20)) |
5703 | DRM_ERROR("Timeout enabling power well\n"); | 5706 | DRM_ERROR("Timeout enabling power well\n"); |
5704 | } | 5707 | } |
5708 | |||
5709 | if (IS_BROADWELL(dev)) { | ||
5710 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | ||
5711 | I915_WRITE(GEN8_DE_PIPE_IMR(PIPE_B), | ||
5712 | dev_priv->de_irq_mask[PIPE_B]); | ||
5713 | I915_WRITE(GEN8_DE_PIPE_IER(PIPE_B), | ||
5714 | ~dev_priv->de_irq_mask[PIPE_B] | | ||
5715 | GEN8_PIPE_VBLANK); | ||
5716 | I915_WRITE(GEN8_DE_PIPE_IMR(PIPE_C), | ||
5717 | dev_priv->de_irq_mask[PIPE_C]); | ||
5718 | I915_WRITE(GEN8_DE_PIPE_IER(PIPE_C), | ||
5719 | ~dev_priv->de_irq_mask[PIPE_C] | | ||
5720 | GEN8_PIPE_VBLANK); | ||
5721 | POSTING_READ(GEN8_DE_PIPE_IER(PIPE_C)); | ||
5722 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | ||
5723 | } | ||
5705 | } else { | 5724 | } else { |
5706 | if (enable_requested) { | 5725 | if (enable_requested) { |
5707 | unsigned long irqflags; | ||
5708 | enum pipe p; | 5726 | enum pipe p; |
5709 | 5727 | ||
5710 | I915_WRITE(HSW_PWR_WELL_DRIVER, 0); | 5728 | I915_WRITE(HSW_PWR_WELL_DRIVER, 0); |
@@ -5731,16 +5749,24 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable) | |||
5731 | static void __intel_power_well_get(struct drm_device *dev, | 5749 | static void __intel_power_well_get(struct drm_device *dev, |
5732 | struct i915_power_well *power_well) | 5750 | struct i915_power_well *power_well) |
5733 | { | 5751 | { |
5734 | if (!power_well->count++) | 5752 | struct drm_i915_private *dev_priv = dev->dev_private; |
5753 | |||
5754 | if (!power_well->count++) { | ||
5755 | hsw_disable_package_c8(dev_priv); | ||
5735 | __intel_set_power_well(dev, true); | 5756 | __intel_set_power_well(dev, true); |
5757 | } | ||
5736 | } | 5758 | } |
5737 | 5759 | ||
5738 | static void __intel_power_well_put(struct drm_device *dev, | 5760 | static void __intel_power_well_put(struct drm_device *dev, |
5739 | struct i915_power_well *power_well) | 5761 | struct i915_power_well *power_well) |
5740 | { | 5762 | { |
5763 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5764 | |||
5741 | WARN_ON(!power_well->count); | 5765 | WARN_ON(!power_well->count); |
5742 | if (!--power_well->count && i915_disable_power_well) | 5766 | if (!--power_well->count && i915_disable_power_well) { |
5743 | __intel_set_power_well(dev, false); | 5767 | __intel_set_power_well(dev, false); |
5768 | hsw_enable_package_c8(dev_priv); | ||
5769 | } | ||
5744 | } | 5770 | } |
5745 | 5771 | ||
5746 | void intel_display_power_get(struct drm_device *dev, | 5772 | void intel_display_power_get(struct drm_device *dev, |
@@ -6130,10 +6156,19 @@ int vlv_freq_opcode(int ddr_freq, int val) | |||
6130 | return val; | 6156 | return val; |
6131 | } | 6157 | } |
6132 | 6158 | ||
6133 | void intel_pm_init(struct drm_device *dev) | 6159 | void intel_pm_setup(struct drm_device *dev) |
6134 | { | 6160 | { |
6135 | struct drm_i915_private *dev_priv = dev->dev_private; | 6161 | struct drm_i915_private *dev_priv = dev->dev_private; |
6136 | 6162 | ||
6163 | mutex_init(&dev_priv->rps.hw_lock); | ||
6164 | |||
6165 | mutex_init(&dev_priv->pc8.lock); | ||
6166 | dev_priv->pc8.requirements_met = false; | ||
6167 | dev_priv->pc8.gpu_idle = false; | ||
6168 | dev_priv->pc8.irqs_disabled = false; | ||
6169 | dev_priv->pc8.enabled = false; | ||
6170 | dev_priv->pc8.disable_count = 2; /* requirements_met + gpu_idle */ | ||
6171 | INIT_DELAYED_WORK(&dev_priv->pc8.enable_work, hsw_enable_pc8_work); | ||
6137 | INIT_DELAYED_WORK(&dev_priv->rps.delayed_resume_work, | 6172 | INIT_DELAYED_WORK(&dev_priv->rps.delayed_resume_work, |
6138 | intel_gen6_powersave_work); | 6173 | intel_gen6_powersave_work); |
6139 | } | 6174 | } |