aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorImre Deak <imre.deak@intel.com>2016-04-18 07:48:21 -0400
committerImre Deak <imre.deak@intel.com>2016-04-19 05:33:48 -0400
commitf74ed08d55a059a20dc1e513edc51c18dfaf2add (patch)
tree3dc05c647eae7669f66089bb37d996e0a07ae22e /drivers/gpu
parentbf93ba67e9c05882f05b7ca2d773cfc8bf462c2a (diff)
drm/i915/gen9: Fix runtime PM refcounting in case DMC firmware isn't loaded
While we disable runtime PM and with that display power well support if the DMC firmware isn't loaded, we still want to disable power wells during system suspend and driver unload. So drop/reacquire the corresponding power refcount during suspend/resume and driver unloading. This also means we have to check if DMC is not loaded and skip enabling DC states in the power well code. v2: - Reuse intel_csr_ucode_suspend() in intel_csr_ucode_fini() instead of opencoding the former. (Chris) - Add docbook comment to the public resume and suspend functions. CC: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1460980101-14713-1-git-send-email-imre.deak@intel.com
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c5
-rw-r--r--drivers/gpu/drm/i915/intel_csr.c44
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h2
-rw-r--r--drivers/gpu/drm/i915/intel_runtime_pm.c3
4 files changed, 50 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 735df5595b34..1b449f96d2c1 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -640,8 +640,7 @@ static int i915_drm_suspend(struct drm_device *dev)
640 640
641 intel_display_set_init_power(dev_priv, false); 641 intel_display_set_init_power(dev_priv, false);
642 642
643 if (HAS_CSR(dev_priv)) 643 intel_csr_ucode_suspend(dev_priv);
644 flush_work(&dev_priv->csr.work);
645 644
646out: 645out:
647 enable_rpm_wakeref_asserts(dev_priv); 646 enable_rpm_wakeref_asserts(dev_priv);
@@ -733,6 +732,8 @@ static int i915_drm_resume(struct drm_device *dev)
733 732
734 disable_rpm_wakeref_asserts(dev_priv); 733 disable_rpm_wakeref_asserts(dev_priv);
735 734
735 intel_csr_ucode_resume(dev_priv);
736
736 mutex_lock(&dev->struct_mutex); 737 mutex_lock(&dev->struct_mutex);
737 i915_gem_restore_gtt_mappings(dev); 738 i915_gem_restore_gtt_mappings(dev);
738 mutex_unlock(&dev->struct_mutex); 739 mutex_unlock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c
index d57b00ed5e5e..a34c23eceba0 100644
--- a/drivers/gpu/drm/i915/intel_csr.c
+++ b/drivers/gpu/drm/i915/intel_csr.c
@@ -467,10 +467,50 @@ void intel_csr_ucode_init(struct drm_i915_private *dev_priv)
467} 467}
468 468
469/** 469/**
470 * intel_csr_ucode_suspend() - prepare CSR firmware before system suspend
471 * @dev_priv: i915 drm device
472 *
473 * Prepare the DMC firmware before entering system suspend. This includes
474 * flushing pending work items and releasing any resources acquired during
475 * init.
476 */
477void intel_csr_ucode_suspend(struct drm_i915_private *dev_priv)
478{
479 if (!HAS_CSR(dev_priv))
480 return;
481
482 flush_work(&dev_priv->csr.work);
483
484 /* Drop the reference held in case DMC isn't loaded. */
485 if (!dev_priv->csr.dmc_payload)
486 intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
487}
488
489/**
490 * intel_csr_ucode_resume() - init CSR firmware during system resume
491 * @dev_priv: i915 drm device
492 *
493 * Reinitialize the DMC firmware during system resume, reacquiring any
494 * resources released in intel_csr_ucode_suspend().
495 */
496void intel_csr_ucode_resume(struct drm_i915_private *dev_priv)
497{
498 if (!HAS_CSR(dev_priv))
499 return;
500
501 /*
502 * Reacquire the reference to keep RPM disabled in case DMC isn't
503 * loaded.
504 */
505 if (!dev_priv->csr.dmc_payload)
506 intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
507}
508
509/**
470 * intel_csr_ucode_fini() - unload the CSR firmware. 510 * intel_csr_ucode_fini() - unload the CSR firmware.
471 * @dev_priv: i915 drm device. 511 * @dev_priv: i915 drm device.
472 * 512 *
473 * Firmmware unloading includes freeing the internal momory and reset the 513 * Firmmware unloading includes freeing the internal memory and reset the
474 * firmware loading status. 514 * firmware loading status.
475 */ 515 */
476void intel_csr_ucode_fini(struct drm_i915_private *dev_priv) 516void intel_csr_ucode_fini(struct drm_i915_private *dev_priv)
@@ -478,7 +518,7 @@ void intel_csr_ucode_fini(struct drm_i915_private *dev_priv)
478 if (!HAS_CSR(dev_priv)) 518 if (!HAS_CSR(dev_priv))
479 return; 519 return;
480 520
481 flush_work(&dev_priv->csr.work); 521 intel_csr_ucode_suspend(dev_priv);
482 522
483 kfree(dev_priv->csr.dmc_payload); 523 kfree(dev_priv->csr.dmc_payload);
484} 524}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 10dfe7251b85..beed9e81252b 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1275,6 +1275,8 @@ u32 skl_plane_ctl_rotation(unsigned int rotation);
1275void intel_csr_ucode_init(struct drm_i915_private *); 1275void intel_csr_ucode_init(struct drm_i915_private *);
1276void intel_csr_load_program(struct drm_i915_private *); 1276void intel_csr_load_program(struct drm_i915_private *);
1277void intel_csr_ucode_fini(struct drm_i915_private *); 1277void intel_csr_ucode_fini(struct drm_i915_private *);
1278void intel_csr_ucode_suspend(struct drm_i915_private *);
1279void intel_csr_ucode_resume(struct drm_i915_private *);
1278 1280
1279/* intel_dp.c */ 1281/* intel_dp.c */
1280void intel_dp_init(struct drm_device *dev, i915_reg_t output_reg, enum port port); 1282void intel_dp_init(struct drm_device *dev, i915_reg_t output_reg, enum port port);
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 1242fb5d3301..0ed3ec862733 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -809,6 +809,9 @@ static void gen9_dc_off_power_well_enable(struct drm_i915_private *dev_priv,
809static void gen9_dc_off_power_well_disable(struct drm_i915_private *dev_priv, 809static void gen9_dc_off_power_well_disable(struct drm_i915_private *dev_priv,
810 struct i915_power_well *power_well) 810 struct i915_power_well *power_well)
811{ 811{
812 if (!dev_priv->csr.dmc_payload)
813 return;
814
812 if (dev_priv->csr.allowed_dc_mask & DC_STATE_EN_UPTO_DC6) 815 if (dev_priv->csr.allowed_dc_mask & DC_STATE_EN_UPTO_DC6)
813 skl_enable_dc6(dev_priv); 816 skl_enable_dc6(dev_priv);
814 else if (dev_priv->csr.allowed_dc_mask & DC_STATE_EN_UPTO_DC5) 817 else if (dev_priv->csr.allowed_dc_mask & DC_STATE_EN_UPTO_DC5)