Skip to content

Commit cb17aa5

Browse files
committed
Merge tag 'drm-intel-next-fixes-2018-03-27' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
- Display fixes for booting with MST hub lid closed and display freezing after hibernation (fd.o bugs 105470 & 105196) - Fix for a very rare interrupt handling race resulting in GPU hang * tag 'drm-intel-next-fixes-2018-03-27' of git://anongit.freedesktop.org/drm/drm-intel: drm/i915: Fix hibernation with ACPI S0 target state drm/i915/execlists: Use a locked clear_bit() for synchronisation with interrupt drm/i915: Specify which engines to reset following semaphore/event lockups drm/i915/dp: Write to SET_POWER dpcd to enable MST hub.
2 parents 2b4f44e + 300efa9 commit cb17aa5

File tree

3 files changed

+19
-26
lines changed

3 files changed

+19
-26
lines changed

drivers/gpu/drm/i915/i915_drv.c

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1611,24 +1611,24 @@ static int i915_drm_suspend_late(struct drm_device *dev, bool hibernation)
16111611
{
16121612
struct drm_i915_private *dev_priv = to_i915(dev);
16131613
struct pci_dev *pdev = dev_priv->drm.pdev;
1614-
bool fw_csr;
16151614
int ret;
16161615

16171616
disable_rpm_wakeref_asserts(dev_priv);
16181617

16191618
intel_display_set_init_power(dev_priv, false);
16201619

1621-
fw_csr = !IS_GEN9_LP(dev_priv) && !hibernation &&
1622-
suspend_to_idle(dev_priv) && dev_priv->csr.dmc_payload;
16231620
/*
16241621
* In case of firmware assisted context save/restore don't manually
16251622
* deinit the power domains. This also means the CSR/DMC firmware will
16261623
* stay active, it will power down any HW resources as required and
16271624
* also enable deeper system power states that would be blocked if the
16281625
* firmware was inactive.
16291626
*/
1630-
if (!fw_csr)
1627+
if (IS_GEN9_LP(dev_priv) || hibernation || !suspend_to_idle(dev_priv) ||
1628+
dev_priv->csr.dmc_payload == NULL) {
16311629
intel_power_domains_suspend(dev_priv);
1630+
dev_priv->power_domains_suspended = true;
1631+
}
16321632

16331633
ret = 0;
16341634
if (IS_GEN9_LP(dev_priv))
@@ -1640,8 +1640,10 @@ static int i915_drm_suspend_late(struct drm_device *dev, bool hibernation)
16401640

16411641
if (ret) {
16421642
DRM_ERROR("Suspend complete failed: %d\n", ret);
1643-
if (!fw_csr)
1643+
if (dev_priv->power_domains_suspended) {
16441644
intel_power_domains_init_hw(dev_priv, true);
1645+
dev_priv->power_domains_suspended = false;
1646+
}
16451647

16461648
goto out;
16471649
}
@@ -1662,8 +1664,6 @@ static int i915_drm_suspend_late(struct drm_device *dev, bool hibernation)
16621664
if (!(hibernation && INTEL_GEN(dev_priv) < 6))
16631665
pci_set_power_state(pdev, PCI_D3hot);
16641666

1665-
dev_priv->suspended_to_idle = suspend_to_idle(dev_priv);
1666-
16671667
out:
16681668
enable_rpm_wakeref_asserts(dev_priv);
16691669

@@ -1830,17 +1830,15 @@ static int i915_drm_resume_early(struct drm_device *dev)
18301830
intel_uncore_resume_early(dev_priv);
18311831

18321832
if (IS_GEN9_LP(dev_priv)) {
1833-
if (!dev_priv->suspended_to_idle)
1834-
gen9_sanitize_dc_state(dev_priv);
1833+
gen9_sanitize_dc_state(dev_priv);
18351834
bxt_disable_dc9(dev_priv);
18361835
} else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
18371836
hsw_disable_pc8(dev_priv);
18381837
}
18391838

18401839
intel_uncore_sanitize(dev_priv);
18411840

1842-
if (IS_GEN9_LP(dev_priv) ||
1843-
!(dev_priv->suspended_to_idle && dev_priv->csr.dmc_payload))
1841+
if (dev_priv->power_domains_suspended)
18441842
intel_power_domains_init_hw(dev_priv, true);
18451843
else
18461844
intel_display_set_init_power(dev_priv, true);
@@ -1850,7 +1848,7 @@ static int i915_drm_resume_early(struct drm_device *dev)
18501848
enable_rpm_wakeref_asserts(dev_priv);
18511849

18521850
out:
1853-
dev_priv->suspended_to_idle = false;
1851+
dev_priv->power_domains_suspended = false;
18541852

18551853
return ret;
18561854
}

drivers/gpu/drm/i915/i915_drv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2119,7 +2119,7 @@ struct drm_i915_private {
21192119
u32 bxt_phy_grc;
21202120

21212121
u32 suspend_count;
2122-
bool suspended_to_idle;
2122+
bool power_domains_suspended;
21232123
struct i915_suspend_saved_registers regfile;
21242124
struct vlv_s0ix_state vlv_s0ix_state;
21252125

drivers/gpu/drm/i915/intel_lrc.c

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,8 @@ static void execlists_submission_tasklet(unsigned long data)
831831
struct drm_i915_private *dev_priv = engine->i915;
832832
bool fw = false;
833833

834-
/* We can skip acquiring intel_runtime_pm_get() here as it was taken
834+
/*
835+
* We can skip acquiring intel_runtime_pm_get() here as it was taken
835836
* on our behalf by the request (see i915_gem_mark_busy()) and it will
836837
* not be relinquished until the device is idle (see
837838
* i915_gem_idle_work_handler()). As a precaution, we make sure
@@ -840,7 +841,8 @@ static void execlists_submission_tasklet(unsigned long data)
840841
*/
841842
GEM_BUG_ON(!dev_priv->gt.awake);
842843

843-
/* Prefer doing test_and_clear_bit() as a two stage operation to avoid
844+
/*
845+
* Prefer doing test_and_clear_bit() as a two stage operation to avoid
844846
* imposing the cost of a locked atomic transaction when submitting a
845847
* new request (outside of the context-switch interrupt).
846848
*/
@@ -856,17 +858,10 @@ static void execlists_submission_tasklet(unsigned long data)
856858
execlists->csb_head = -1; /* force mmio read of CSB ptrs */
857859
}
858860

859-
/* The write will be ordered by the uncached read (itself
860-
* a memory barrier), so we do not need another in the form
861-
* of a locked instruction. The race between the interrupt
862-
* handler and the split test/clear is harmless as we order
863-
* our clear before the CSB read. If the interrupt arrived
864-
* first between the test and the clear, we read the updated
865-
* CSB and clear the bit. If the interrupt arrives as we read
866-
* the CSB or later (i.e. after we had cleared the bit) the bit
867-
* is set and we do a new loop.
868-
*/
869-
__clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted);
861+
/* Clear before reading to catch new interrupts */
862+
clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted);
863+
smp_mb__after_atomic();
864+
870865
if (unlikely(execlists->csb_head == -1)) { /* following a reset */
871866
if (!fw) {
872867
intel_uncore_forcewake_get(dev_priv,

0 commit comments

Comments
 (0)