Skip to content

Commit 2cd9a68

Browse files
committed
drm/i915: Refactor intel_display_set_init_power() logic
The device global init_power_on flag is somewhat arbitrary and makes debugging power refcounting problems difficult. Instead arrange things so that all display power domain get has a corresponding put call. After this change we have the following sequences: driver loading: intel_power_domains_init_hw(); <other init steps> intel_power_domains_enable(); driver unloading: intel_power_domains_disable(); <other uninit steps> intel_power_domains_fini_hw(); system suspend: intel_power_domains_disable(); <other suspend steps> intel_power_domains_suspend(); system resume: intel_power_domains_resume(); <other resume steps> intel_power_domains_enable(); at other times while the driver is loaded: intel_display_power_get(); ... intel_display_power_put(); Suggested-by: Chris Wilson <[email protected]> Cc: Chris Wilson <[email protected]> Signed-off-by: Imre Deak <[email protected]> Reviewed-by: Chris Wilson <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 07d8057 commit 2cd9a68

File tree

5 files changed

+142
-78
lines changed

5 files changed

+142
-78
lines changed

drivers/gpu/drm/i915/i915_drv.c

Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1282,6 +1282,7 @@ static void i915_driver_register(struct drm_i915_private *dev_priv)
12821282
if (INTEL_INFO(dev_priv)->num_pipes)
12831283
drm_kms_helper_poll_init(dev);
12841284

1285+
intel_power_domains_enable(dev_priv);
12851286
intel_runtime_pm_enable(dev_priv);
12861287
}
12871288

@@ -1292,6 +1293,7 @@ static void i915_driver_register(struct drm_i915_private *dev_priv)
12921293
static void i915_driver_unregister(struct drm_i915_private *dev_priv)
12931294
{
12941295
intel_runtime_pm_disable(dev_priv);
1296+
intel_power_domains_disable(dev_priv);
12951297

12961298
intel_fbdev_unregister(dev_priv);
12971299
intel_audio_deinit(dev_priv);
@@ -1374,7 +1376,7 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent)
13741376
if (ret < 0)
13751377
goto out_pci_disable;
13761378

1377-
intel_runtime_pm_get(dev_priv);
1379+
disable_rpm_wakeref_asserts(dev_priv);
13781380

13791381
ret = i915_driver_init_mmio(dev_priv);
13801382
if (ret < 0)
@@ -1404,7 +1406,7 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent)
14041406

14051407
intel_init_ipc(dev_priv);
14061408

1407-
intel_runtime_pm_put(dev_priv);
1409+
enable_rpm_wakeref_asserts(dev_priv);
14081410

14091411
i915_welcome_messages(dev_priv);
14101412

@@ -1415,7 +1417,7 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent)
14151417
out_cleanup_mmio:
14161418
i915_driver_cleanup_mmio(dev_priv);
14171419
out_runtime_pm_put:
1418-
intel_runtime_pm_put(dev_priv);
1420+
enable_rpm_wakeref_asserts(dev_priv);
14191421
i915_driver_cleanup_early(dev_priv);
14201422
out_pci_disable:
14211423
pci_disable_device(pdev);
@@ -1433,7 +1435,7 @@ void i915_driver_unload(struct drm_device *dev)
14331435
struct drm_i915_private *dev_priv = to_i915(dev);
14341436
struct pci_dev *pdev = dev_priv->drm.pdev;
14351437

1436-
intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
1438+
disable_rpm_wakeref_asserts(dev_priv);
14371439

14381440
i915_driver_unregister(dev_priv);
14391441

@@ -1465,7 +1467,8 @@ void i915_driver_unload(struct drm_device *dev)
14651467
i915_driver_cleanup_hw(dev_priv);
14661468
i915_driver_cleanup_mmio(dev_priv);
14671469

1468-
intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
1470+
enable_rpm_wakeref_asserts(dev_priv);
1471+
14691472
WARN_ON(atomic_read(&dev_priv->runtime_pm.wakeref_count));
14701473
}
14711474

@@ -1575,7 +1578,7 @@ static int i915_drm_suspend(struct drm_device *dev)
15751578

15761579
/* We do a lot of poking in a lot of registers, make sure they work
15771580
* properly. */
1578-
intel_display_set_init_power(dev_priv, true);
1581+
intel_power_domains_disable(dev_priv);
15791582

15801583
drm_kms_helper_poll_disable(dev);
15811584

@@ -1612,6 +1615,18 @@ static int i915_drm_suspend(struct drm_device *dev)
16121615
return 0;
16131616
}
16141617

1618+
static enum i915_drm_suspend_mode
1619+
get_suspend_mode(struct drm_i915_private *dev_priv, bool hibernate)
1620+
{
1621+
if (hibernate)
1622+
return I915_DRM_SUSPEND_HIBERNATE;
1623+
1624+
if (suspend_to_idle(dev_priv))
1625+
return I915_DRM_SUSPEND_IDLE;
1626+
1627+
return I915_DRM_SUSPEND_MEM;
1628+
}
1629+
16151630
static int i915_drm_suspend_late(struct drm_device *dev, bool hibernation)
16161631
{
16171632
struct drm_i915_private *dev_priv = to_i915(dev);
@@ -1622,21 +1637,10 @@ static int i915_drm_suspend_late(struct drm_device *dev, bool hibernation)
16221637

16231638
i915_gem_suspend_late(dev_priv);
16241639

1625-
intel_display_set_init_power(dev_priv, false);
16261640
intel_uncore_suspend(dev_priv);
16271641

1628-
/*
1629-
* In case of firmware assisted context save/restore don't manually
1630-
* deinit the power domains. This also means the CSR/DMC firmware will
1631-
* stay active, it will power down any HW resources as required and
1632-
* also enable deeper system power states that would be blocked if the
1633-
* firmware was inactive.
1634-
*/
1635-
if (IS_GEN9_LP(dev_priv) || hibernation || !suspend_to_idle(dev_priv) ||
1636-
dev_priv->csr.dmc_payload == NULL) {
1637-
intel_power_domains_suspend(dev_priv);
1638-
dev_priv->power_domains_suspended = true;
1639-
}
1642+
intel_power_domains_suspend(dev_priv,
1643+
get_suspend_mode(dev_priv, hibernation));
16401644

16411645
ret = 0;
16421646
if (IS_GEN9_LP(dev_priv))
@@ -1648,10 +1652,7 @@ static int i915_drm_suspend_late(struct drm_device *dev, bool hibernation)
16481652

16491653
if (ret) {
16501654
DRM_ERROR("Suspend complete failed: %d\n", ret);
1651-
if (dev_priv->power_domains_suspended) {
1652-
intel_power_domains_init_hw(dev_priv, true);
1653-
dev_priv->power_domains_suspended = false;
1654-
}
1655+
intel_power_domains_resume(dev_priv);
16551656

16561657
goto out;
16571658
}
@@ -1768,6 +1769,8 @@ static int i915_drm_resume(struct drm_device *dev)
17681769

17691770
intel_opregion_notify_adapter(dev_priv, PCI_D0);
17701771

1772+
intel_power_domains_enable(dev_priv);
1773+
17711774
enable_rpm_wakeref_asserts(dev_priv);
17721775

17731776
return 0;
@@ -1802,7 +1805,7 @@ static int i915_drm_resume_early(struct drm_device *dev)
18021805
ret = pci_set_power_state(pdev, PCI_D0);
18031806
if (ret) {
18041807
DRM_ERROR("failed to set PCI D0 power state (%d)\n", ret);
1805-
goto out;
1808+
return ret;
18061809
}
18071810

18081811
/*
@@ -1818,10 +1821,8 @@ static int i915_drm_resume_early(struct drm_device *dev)
18181821
* depend on the device enable refcount we can't anyway depend on them
18191822
* disabling/enabling the device.
18201823
*/
1821-
if (pci_enable_device(pdev)) {
1822-
ret = -EIO;
1823-
goto out;
1824-
}
1824+
if (pci_enable_device(pdev))
1825+
return -EIO;
18251826

18261827
pci_set_master(pdev);
18271828

@@ -1844,18 +1845,12 @@ static int i915_drm_resume_early(struct drm_device *dev)
18441845

18451846
intel_uncore_sanitize(dev_priv);
18461847

1847-
if (dev_priv->power_domains_suspended)
1848-
intel_power_domains_init_hw(dev_priv, true);
1849-
else
1850-
intel_display_set_init_power(dev_priv, true);
1848+
intel_power_domains_resume(dev_priv);
18511849

18521850
intel_engines_sanitize(dev_priv);
18531851

18541852
enable_rpm_wakeref_asserts(dev_priv);
18551853

1856-
out:
1857-
dev_priv->power_domains_suspended = false;
1858-
18591854
return ret;
18601855
}
18611856

drivers/gpu/drm/i915/i915_drv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -935,8 +935,8 @@ struct i915_power_domains {
935935
* Power wells needed for initialization at driver init and suspend
936936
* time are on. They are kept on until after the first modeset.
937937
*/
938-
bool init_power_on;
939938
bool initializing;
939+
bool display_core_suspended;
940940
int power_well_count;
941941

942942
struct mutex lock;

drivers/gpu/drm/i915/intel_display.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15846,6 +15846,8 @@ intel_modeset_setup_hw_state(struct drm_device *dev,
1584615846
struct intel_encoder *encoder;
1584715847
int i;
1584815848

15849+
intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
15850+
1584915851
intel_early_display_was(dev_priv);
1585015852
intel_modeset_readout_hw_state(dev);
1585115853

@@ -15900,7 +15902,8 @@ intel_modeset_setup_hw_state(struct drm_device *dev,
1590015902
if (WARN_ON(put_domains))
1590115903
modeset_put_power_domains(dev_priv, put_domains);
1590215904
}
15903-
intel_display_set_init_power(dev_priv, false);
15905+
15906+
intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
1590415907

1590515908
intel_power_domains_verify_state(dev_priv);
1590615909

drivers/gpu/drm/i915/intel_drv.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1954,7 +1954,18 @@ int intel_power_domains_init(struct drm_i915_private *);
19541954
void intel_power_domains_cleanup(struct drm_i915_private *dev_priv);
19551955
void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume);
19561956
void intel_power_domains_fini_hw(struct drm_i915_private *dev_priv);
1957-
void intel_power_domains_suspend(struct drm_i915_private *dev_priv);
1957+
void intel_power_domains_enable(struct drm_i915_private *dev_priv);
1958+
void intel_power_domains_disable(struct drm_i915_private *dev_priv);
1959+
1960+
enum i915_drm_suspend_mode {
1961+
I915_DRM_SUSPEND_IDLE,
1962+
I915_DRM_SUSPEND_MEM,
1963+
I915_DRM_SUSPEND_HIBERNATE,
1964+
};
1965+
1966+
void intel_power_domains_suspend(struct drm_i915_private *dev_priv,
1967+
enum i915_drm_suspend_mode);
1968+
void intel_power_domains_resume(struct drm_i915_private *dev_priv);
19581969
void intel_power_domains_verify_state(struct drm_i915_private *dev_priv);
19591970
void bxt_display_core_init(struct drm_i915_private *dev_priv, bool resume);
19601971
void bxt_display_core_uninit(struct drm_i915_private *dev_priv);
@@ -2037,8 +2048,6 @@ bool intel_runtime_pm_get_if_in_use(struct drm_i915_private *dev_priv);
20372048
void intel_runtime_pm_get_noresume(struct drm_i915_private *dev_priv);
20382049
void intel_runtime_pm_put(struct drm_i915_private *dev_priv);
20392050

2040-
void intel_display_set_init_power(struct drm_i915_private *dev, bool enable);
2041-
20422051
void chv_phy_powergate_lanes(struct intel_encoder *encoder,
20432052
bool override, unsigned int mask);
20442053
bool chv_phy_powergate_ch(struct drm_i915_private *dev_priv, enum dpio_phy phy,

0 commit comments

Comments
 (0)