summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaulo Zanoni <paulo.r.zanoni@intel.com>2013-07-12 13:45:50 -0300
committerPaulo Zanoni <paulo.r.zanoni@intel.com>2013-07-15 12:09:30 -0300
commit1490e4b3210fc39a7ba69760b9467cbdfb3afd98 (patch)
tree438b36cd7ffa555c5cb9e59d82926131d4ab33c8
parentf57a3b4d0391cb39d71f3a26286249c4c47a2370 (diff)
XXX: allow package C8 (with racing conditions)c8-wip
Yay! Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c4
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h6
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c211
-rw-r--r--drivers/gpu/drm/i915/intel_display.c105
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h2
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c6
6 files changed, 271 insertions, 63 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 6ce903306320..d3398b7b51cf 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1609,10 +1609,14 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
spin_lock_init(&dev_priv->gpu_error.lock);
spin_lock_init(&dev_priv->backlight.lock);
mutex_init(&dev_priv->dpio_lock);
+ mutex_init(&dev_priv->c8_lock);
mutex_init(&dev_priv->rps.hw_lock);
mutex_init(&dev_priv->modeset_restore_lock);
+ dev_priv->allowing_package_c8 = false;
+ dev_priv->c8_forbid_refcnt = 1;
+
dev_priv->num_plane = 1;
if (IS_VALLEYVIEW(dev))
dev_priv->num_plane = 2;
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index cef35d3ab37b..578d9fa0d5fc 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -384,6 +384,8 @@ struct drm_i915_display_funcs {
int (*update_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb,
int x, int y);
void (*hpd_irq_setup)(struct drm_device *dev);
+ void (*irq_uninstall)(struct drm_device *dev, bool disable_pch_hpd,
+ bool disable_others, bool disable_master);
/* clock updates for mode set */
/* cursor updates */
/* render clock increase/decrease */
@@ -1184,6 +1186,10 @@ typedef struct drm_i915_private {
struct i915_suspend_saved_registers regfile;
+ bool allowing_package_c8;
+ int c8_forbid_refcnt;
+ struct mutex c8_lock;
+
/* Old dri1 support infrastructure, beware the dragons ya fools entering
* here! */
struct i915_dri1_state dri1;
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index b02c97c62ec1..7193cf8d8f74 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -79,6 +79,26 @@ static const u32 hpd_status_i915[] = { /* i915 and valleyview are the same */
[HPD_PORT_D] = PORTD_HOTPLUG_INT_STATUS
};
+static void intel_irq_iir_reset16(struct drm_i915_private *dev_priv,
+ uint32_t iir)
+{
+ I915_WRITE16(iir, 0xffff);
+ if (I915_READ16(iir)) {
+ I915_WRITE16(iir, 0xffff);
+ POSTING_READ16(iir);
+ }
+}
+
+static void intel_irq_iir_reset(struct drm_i915_private *dev_priv,
+ uint32_t iir)
+{
+ I915_WRITE(iir, 0xffffffff);
+ if (I915_READ(iir)) {
+ I915_WRITE(iir, 0xffffffff);
+ POSTING_READ(iir);
+ }
+}
+
static void intel_irq_reg_reset16(struct drm_i915_private *dev_priv,
uint32_t ier, uint32_t imr, uint32_t iir)
{
@@ -89,12 +109,7 @@ static void intel_irq_reg_reset16(struct drm_i915_private *dev_priv,
} else {
POSTING_READ16(imr);
}
-
- I915_WRITE16(iir, 0xffff);
- if (I915_READ16(iir)) {
- I915_WRITE16(iir, 0xffff);
- POSTING_READ16(iir);
- }
+ intel_irq_iir_reset16(dev_priv, iir);
}
static void intel_irq_reg_reset(struct drm_i915_private *dev_priv, uint32_t ier,
@@ -107,21 +122,20 @@ static void intel_irq_reg_reset(struct drm_i915_private *dev_priv, uint32_t ier,
} else {
POSTING_READ(imr);
}
-
- I915_WRITE(iir, 0xffffffff);
- if (I915_READ(iir)) {
- I915_WRITE(iir, 0xffffffff);
- POSTING_READ(iir);
- }
+ intel_irq_iir_reset(dev_priv, iir);
}
static void intel_irq_reg_init16(struct drm_i915_private *dev_priv,
uint32_t ier, uint16_t ier_val, uint32_t imr,
- uint16_t imr_val, uint32_t iir)
+ uint16_t imr_val, uint32_t iir,
+ bool check_state)
{
- WARN(I915_READ16(iir) != 0, "Register 0x%x is not zero\n", iir);
- WARN(I915_READ16(imr) != 0xffff, "Register 0x%x is not 0xffff\n", imr);
- WARN(I915_READ16(ier) != 0, "Register 0x%x is not zero\n", ier);
+ if (check_state) {
+ WARN(I915_READ16(iir) != 0, "Register 0x%x is not zero\n", iir);
+ WARN(I915_READ16(imr) != 0xffff,
+ "Register 0x%x is not 0xffff\n", imr);
+ WARN(I915_READ16(ier) != 0, "Register 0x%x is not zero\n", ier);
+ }
I915_WRITE16(imr, imr_val);
I915_WRITE16(ier, ier_val);
POSTING_READ16(ier);
@@ -129,12 +143,14 @@ static void intel_irq_reg_init16(struct drm_i915_private *dev_priv,
static void intel_irq_reg_init(struct drm_i915_private *dev_priv, uint32_t ier,
uint32_t ier_val, uint32_t imr, uint32_t imr_val,
- uint32_t iir)
+ uint32_t iir, bool check_state)
{
- WARN(I915_READ(iir) != 0, "Register 0x%x is not zero\n", iir);
- WARN(I915_READ(imr) != 0xffffffff, "Register 0x%x is not 0xffffffff\n",
- imr);
- WARN(I915_READ(ier) != 0, "Register 0x%x is not zero\n", ier);
+ if (check_state) {
+ WARN(I915_READ(iir) != 0, "Register 0x%x is not zero\n", iir);
+ WARN(I915_READ(imr) != 0xffffffff,
+ "Register 0x%x is not 0xffffffff\n", imr);
+ WARN(I915_READ(ier) != 0, "Register 0x%x is not zero\n", ier);
+ }
I915_WRITE(imr, imr_val);
I915_WRITE(ier, ier_val);
POSTING_READ(ier);
@@ -2041,32 +2057,59 @@ void i915_hangcheck_elapsed(unsigned long data)
DRM_I915_HANGCHECK_JIFFIES));
}
-static void ibx_irq_reset(struct drm_device *dev)
+static void ibx_irq_reset(struct drm_device *dev, bool disable_pch_hpd,
+ bool disable_others)
{
struct drm_i915_private *dev_priv = dev->dev_private;
enum pipe pipe;
+ uint32_t hotplug_mask, others_mask, sdeier_val, sdeimr_val;
if (HAS_PCH_NOP(dev))
return;
- intel_irq_reg_reset(dev_priv, SDEIER, SDEIMR, SDEIIR);
- if (HAS_PCH_CPT(dev) || HAS_PCH_LPT(dev))
- I915_WRITE(SERR_INT, 0xffffffff);
+ hotplug_mask = HAS_PCH_IBX(dev) ?
+ SDE_HOTPLUG_MASK : SDE_HOTPLUG_MASK_CPT;
+ others_mask = ~hotplug_mask;
+ sdeier_val = I915_READ(SDEIER);
+ sdeimr_val = I915_READ(SDEIMR);
- for_each_pipe(pipe) {
- /* No pixel path on LPT_LP. */
- if (dev_priv->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE)
- break;
+ if (disable_pch_hpd) {
+ sdeier_val &= ~hotplug_mask;
+ sdeimr_val |= hotplug_mask;
+ }
- intel_irq_reg_reset(dev_priv, 0, FDI_RX_IMR(pipe),
- FDI_RX_IIR(pipe));
- /* Only 1 PCH transcoder. */
- if (HAS_PCH_LPT(dev))
- break;
+ if (disable_others) {
+ sdeier_val &= ~others_mask;
+ sdeimr_val |= others_mask;
}
- if (HAS_PCH_LPT(dev))
- intel_irq_reg_reset(dev_priv, 0, PCH_GTCIMR, PCH_GTCIIR);
+ DRM_DEBUG_KMS("=== sdeier_val:0x%x sdeimr_val:0x%x, pch:%d others:%d\n",
+ sdeier_val, sdeimr_val, disable_pch_hpd, disable_others);
+ //intel_irq_reg_reset(dev_priv, SDEIER, SDEIMR, SDEIIR);
+ I915_WRITE(SDEIMR, sdeimr_val);
+ I915_WRITE(SDEIER, sdeier_val);
+ POSTING_READ(SDEIER);
+ intel_irq_iir_reset(dev_priv, SDEIIR);
+
+ if (disable_others) {
+ if (HAS_PCH_CPT(dev) || HAS_PCH_LPT(dev))
+ I915_WRITE(SERR_INT, 0xffffffff);
+
+ for_each_pipe(pipe) {
+ /* No pixel path on LPT_LP. */
+ if (dev_priv->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE)
+ break;
+
+ intel_irq_reg_reset(dev_priv, 0, FDI_RX_IMR(pipe),
+ FDI_RX_IIR(pipe));
+ /* Only 1 PCH transcoder. */
+ if (HAS_PCH_LPT(dev))
+ break;
+ }
+
+ if (HAS_PCH_LPT(dev))
+ intel_irq_reg_reset(dev_priv, 0, PCH_GTCIMR, PCH_GTCIIR);
+ }
}
static void gen5_gt_irq_reset(struct drm_device *dev)
@@ -2082,24 +2125,54 @@ static void gen5_gt_irq_reset(struct drm_device *dev)
/* drm_dma.h hooks
*/
-static void ironlake_irq_reset(struct drm_device *dev)
+static void ironlake_irq_reset(struct drm_device *dev, bool disable_pch_hpd,
+ bool disable_others, bool disable_master)
{
struct drm_i915_private *dev_priv = dev->dev_private;
+ uint32_t deier_val, deimr_val, pch_hpd_bit, others_bits;
+
+ pch_hpd_bit = (INTEL_INFO(dev)->gen >= 7) ?
+ DE_PCH_EVENT_IVB : DE_PCH_EVENT;
+ others_bits = ~(pch_hpd_bit | DE_MASTER_IRQ_CONTROL);
+
+ deier_val = I915_READ(DEIER);
+ deimr_val = I915_READ(DEIMR);
+
+ if (disable_pch_hpd) {
+ deier_val &= ~pch_hpd_bit;
+ deimr_val |= pch_hpd_bit;
+ }
+ if (disable_others)
+ deier_val &= ~others_bits;
+ deimr_val |= others_bits;
+ if (disable_master)
+ deier_val &= ~DE_MASTER_IRQ_CONTROL;
+
+ if (disable_others)
+ I915_WRITE(HWSTAM, 0xffffffff);
+
+ //intel_irq_reg_reset(dev_priv, DEIER, DEIMR, DEIIR);
+ DRM_DEBUG_KMS("=== deier:0x%x deimr:0x%x hpd:%d others:%d master:%d\n",
+ deier_val, deimr_val, disable_pch_hpd, disable_others,
+ disable_master);
+ I915_WRITE(DEIMR, deimr_val);
+ I915_WRITE(DEIER, deier_val);
+ POSTING_READ(DEIER);
+ intel_irq_iir_reset(dev_priv, DEIIR);
- I915_WRITE(HWSTAM, 0xffffffff);
+ if (disable_others) {
+ if (IS_GEN7(dev))
+ I915_WRITE(GEN7_ERR_INT, 0xffffffff);
- intel_irq_reg_reset(dev_priv, DEIER, DEIMR, DEIIR);
- if (IS_GEN7(dev))
- I915_WRITE(GEN7_ERR_INT, 0xffffffff);
+ gen5_gt_irq_reset(dev);
- gen5_gt_irq_reset(dev);
-
- if (IS_HASWELL(dev)) {
- intel_irq_reg_reset(dev_priv, AUDIER, AUDIMR, AUDIIR);
- intel_irq_reg_reset(dev_priv, 0, SRDIMR, SRDIIR);
+ if (IS_HASWELL(dev)) {
+ intel_irq_reg_reset(dev_priv, AUDIER, AUDIMR, AUDIIR);
+ intel_irq_reg_reset(dev_priv, 0, SRDIMR, SRDIIR);
+ }
}
- ibx_irq_reset(dev);
+ ibx_irq_reset(dev, disable_pch_hpd, disable_others);
}
static void ironlake_irq_preinstall(struct drm_device *dev)
@@ -2108,7 +2181,7 @@ static void ironlake_irq_preinstall(struct drm_device *dev)
atomic_set(&dev_priv->irq_received, 0);
- ironlake_irq_reset(dev);
+ ironlake_irq_reset(dev, true, true, true);
}
static void valleyview_irq_preinstall(struct drm_device *dev)
@@ -2194,7 +2267,8 @@ static void ibx_irq_postinstall(struct drm_device *dev)
* is enabled - instead we unconditionally enable all PCH interrupt
* sources here, but then only unmask them as needed with SDEIMR.
*/
- intel_irq_reg_init(dev_priv, SDEIER, 0xffffffff, SDEIMR, ~mask, SDEIIR);
+ intel_irq_reg_init(dev_priv, SDEIER, 0xffffffff, SDEIMR, ~mask, SDEIIR,
+ false);
for_each_pipe(pipe) {
/* No pixel path on LPT_LP. */
@@ -2240,7 +2314,7 @@ static void gen5_gt_irq_postinstall(struct drm_device *dev)
}
intel_irq_reg_init(dev_priv, GTIER, gt_irqs, GTIMR,
- dev_priv->gt_irq_mask, GTIIR);
+ dev_priv->gt_irq_mask, GTIIR, true);
if (INTEL_INFO(dev)->gen >= 6) {
pm_irqs |= GEN6_PM_RPS_EVENTS;
@@ -2249,7 +2323,7 @@ static void gen5_gt_irq_postinstall(struct drm_device *dev)
pm_irqs |= PM_VEBOX_USER_INTERRUPT;
intel_irq_reg_init(dev_priv, GEN6_PMIER, pm_irqs, GEN6_PMIMR,
- 0xffffffff, GEN6_PMIIR);
+ 0xffffffff, GEN6_PMIIR, true);
}
}
@@ -2282,7 +2356,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
dev_priv->irq_mask = ~display_mask;
intel_irq_reg_init(dev_priv, DEIER, display_mask | extra_mask, DEIMR,
- dev_priv->irq_mask, DEIIR);
+ dev_priv->irq_mask, DEIIR, false);
gen5_gt_irq_postinstall(dev);
@@ -2340,7 +2414,7 @@ static int valleyview_irq_postinstall(struct drm_device *dev)
I915_WRITE(PIPESTAT(0), 0xffff);
I915_WRITE(PIPESTAT(1), 0xffff);
intel_irq_reg_init(dev_priv, VLV_IER, enable_mask, VLV_IMR,
- dev_priv->irq_mask, VLV_IIR);
+ dev_priv->irq_mask, VLV_IIR, true);
/* Interrupt setup is already guaranteed to be single-threaded, this is
* just to make the assert_spin_locked check happy. */
@@ -2381,16 +2455,16 @@ static void valleyview_irq_uninstall(struct drm_device *dev)
intel_irq_reg_reset(dev_priv, VLV_IER, VLV_IMR, VLV_IIR);
}
-static void ironlake_irq_uninstall(struct drm_device *dev)
+static void ironlake_irq_uninstall(struct drm_device *dev, bool disable_pch_hpd,
+ bool disable_others, bool disable_master)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
- if (!dev_priv)
- return;
-
- del_timer_sync(&dev_priv->hotplug_reenable_timer);
+ if (disable_pch_hpd)
+ del_timer_sync(&dev_priv->hotplug_reenable_timer);
- ironlake_irq_reset(dev);
+ ironlake_irq_reset(dev, disable_pch_hpd, disable_others,
+ disable_master);
}
static void i8xx_irq_preinstall(struct drm_device * dev)
@@ -2425,7 +2499,7 @@ static int i8xx_irq_postinstall(struct drm_device *dev)
I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT);
intel_irq_reg_init16(dev_priv, IER, enable_mask, IMR,
- dev_priv->irq_mask, IIR);
+ dev_priv->irq_mask, IIR, true);
return 0;
}
@@ -2594,7 +2668,7 @@ static int i915_irq_postinstall(struct drm_device *dev)
}
intel_irq_reg_init(dev_priv, IER, enable_mask, IMR, dev_priv->irq_mask,
- IIR);
+ IIR, true);
i915_enable_asle_pipestat(dev);
@@ -2821,7 +2895,7 @@ static int i965_irq_postinstall(struct drm_device *dev)
I915_WRITE(EMR, error_mask);
intel_irq_reg_init(dev_priv, IER, enable_mask, IMR, dev_priv->irq_mask,
- IIR);
+ IIR, true);
I915_WRITE(PORT_HOTPLUG_EN, 0);
POSTING_READ(PORT_HOTPLUG_EN);
@@ -3037,6 +3111,16 @@ static void i915_reenable_hotplug_timer_func(unsigned long data)
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
}
+static void intel_irq_uninstall(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ if (!dev_priv)
+ return;
+
+ dev_priv->display.irq_uninstall(dev, true, true, true);
+}
+
void intel_irq_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -3079,10 +3163,11 @@ void intel_irq_init(struct drm_device *dev)
dev->driver->irq_handler = ironlake_irq_handler;
dev->driver->irq_preinstall = ironlake_irq_preinstall;
dev->driver->irq_postinstall = ironlake_irq_postinstall;
- dev->driver->irq_uninstall = ironlake_irq_uninstall;
+ dev->driver->irq_uninstall = intel_irq_uninstall;
dev->driver->enable_vblank = ironlake_enable_vblank;
dev->driver->disable_vblank = ironlake_disable_vblank;
dev_priv->display.hpd_irq_setup = ibx_hpd_irq_setup;
+ dev_priv->display.irq_uninstall = ironlake_irq_uninstall;
} else {
if (INTEL_INFO(dev)->gen == 2) {
dev->driver->irq_preinstall = i8xx_irq_preinstall;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 9055f603254d..40d850ac14db 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6045,6 +6045,109 @@ void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
}
}
+void hsw_allow_package_c8(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ uint32_t val;
+
+ WARN_ON(!mutex_is_locked(&dev_priv->c8_lock));
+ WARN(dev_priv->c8_forbid_refcnt < 1,
+ "c8_forbid_refcnt: %d\n", dev_priv->c8_forbid_refcnt);
+
+ dev_priv->c8_forbid_refcnt--;
+ if (dev_priv->c8_forbid_refcnt != 0)
+ return;
+
+ DRM_DEBUG_KMS("Allowing package C8+\n");
+
+ if (dev_priv->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) {
+ val = I915_READ(SOUTH_DSPCLK_GATE_D);
+ val &= ~PCH_LP_PARTITION_LEVEL_DISABLE;
+ I915_WRITE(SOUTH_DSPCLK_GATE_D, val);
+ }
+
+ lpt_disable_clkout_dp(dev);
+// hsw_disable_interrupts(dev_priv);
+ dev_priv->display.irq_uninstall(dev, false, true, false);
+ hsw_disable_lcpll(dev_priv, true, true);
+}
+
+void hsw_disallow_package_c8(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ uint32_t val;
+
+ WARN_ON(!mutex_is_locked(&dev_priv->c8_lock));
+ WARN(dev_priv->c8_forbid_refcnt < 0,
+ "c8_forbid_refcnt: %d\n", dev_priv->c8_forbid_refcnt);
+
+ dev_priv->c8_forbid_refcnt++;
+ if (dev_priv->c8_forbid_refcnt != 1)
+ return;
+
+ DRM_DEBUG_KMS("Disallowing package C8+\n");
+ hsw_restore_lcpll(dev_priv);
+ dev->driver->irq_postinstall(dev);
+// hsw_restore_interrupts(dev_priv);
+ lpt_init_pch_refclk(dev);
+
+ if (dev_priv->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) {
+ val = I915_READ(SOUTH_DSPCLK_GATE_D);
+ val |= PCH_LP_PARTITION_LEVEL_DISABLE;
+ I915_WRITE(SOUTH_DSPCLK_GATE_D, val);
+ }
+
+ intel_prepare_ddi(dev);
+ i915_gem_init_swizzling(dev);
+}
+
+static bool hsw_can_allow_package_c8(struct drm_i915_private *dev_priv)
+{
+ struct drm_device *dev = dev_priv->dev;
+ struct intel_crtc *crtc;
+ uint32_t val;
+
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head)
+ if (crtc->base.enabled)
+ return false;
+
+ /* This case is still possible since we have the i915.disable_power_well
+ * parameter and also the KVMr or something else might be requesting the
+ * power well. */
+ val = I915_READ(HSW_PWR_WELL_DRIVER);
+ if (val != 0) {
+ DRM_DEBUG_KMS("Not allowing PC8: power well on\n");
+ return false;
+ }
+
+ return true;
+}
+
+/* Since we're called from modeset_global_resources there's no way to
+ * symmetrically increase and decrease the refcnt, so we use
+ * dev_priv->allowing_package_c8 to track whether we already have the refcnt or
+ * not. */
+static void hsw_set_package_c8(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ bool allow = hsw_can_allow_package_c8(dev_priv);
+
+ mutex_lock(&dev_priv->c8_lock);
+
+ if (allow == dev_priv->allowing_package_c8)
+ goto done;
+
+ dev_priv->allowing_package_c8 = allow;
+
+ if (allow)
+ hsw_allow_package_c8(dev);
+ else
+ hsw_disallow_package_c8(dev);
+
+done:
+ mutex_unlock(&dev_priv->c8_lock);
+}
+
static void haswell_modeset_global_resources(struct drm_device *dev)
{
bool enable = false;
@@ -6060,6 +6163,8 @@ static void haswell_modeset_global_resources(struct drm_device *dev)
}
intel_set_power_well(dev, enable);
+
+ hsw_set_package_c8(dev);
}
static int haswell_crtc_mode_set(struct drm_crtc *crtc,
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index a64de602566d..e506abcbb9ec 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -837,5 +837,7 @@ extern void hsw_disable_lcpll(struct drm_i915_private *dev_priv,
extern void hsw_restore_lcpll(struct drm_i915_private *dev_priv);
extern void intel_aux_display_runtime_get(struct drm_i915_private *dev_priv);
extern void intel_aux_display_runtime_put(struct drm_i915_private *dev_priv);
+extern void hsw_allow_package_c8(struct drm_device *dev);
+extern void hsw_disallow_package_c8(struct drm_device *dev);
#endif /* __INTEL_DRV_H__ */
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index c109993e9c8a..1e0d9273b9a8 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5151,10 +5151,16 @@ void intel_init_power_well(struct drm_device *dev)
void intel_aux_display_runtime_get(struct drm_i915_private *dev_priv)
{
+ mutex_lock(&dev_priv->c8_lock);
+ hsw_disallow_package_c8(dev_priv->dev);
+ mutex_unlock(&dev_priv->c8_lock);
}
void intel_aux_display_runtime_put(struct drm_i915_private *dev_priv)
{
+ mutex_lock(&dev_priv->c8_lock);
+ hsw_allow_package_c8(dev_priv->dev);
+ mutex_unlock(&dev_priv->c8_lock);
}
/* Set up chip specific power management-related functions */