diff options
author | Rodrigo Vivi <rodrigo.vivi@intel.com> | 2023-07-26 01:11:59 +0300 |
---|---|---|
committer | Rodrigo Vivi <rodrigo.vivi@intel.com> | 2023-12-21 19:39:16 +0300 |
commit | d87c424afaf62f11ded6e66b4bdfbd5f5da8b330 (patch) | |
tree | 6d89a2cd52d179c729b2015a2f598781cbdf19c2 | |
parent | a32d82b4cfd63a9bc198bd9faa54844b8d04c5d3 (diff) | |
download | linux-d87c424afaf62f11ded6e66b4bdfbd5f5da8b330.tar.xz |
drm/xe: Ensure memory eviction on s2idle.
On discrete cards we cannot allow the pci subsystem to skip
the regular suspend and we need to unblock the d3cold.
Cc: Anshuman Gupta <anshuman.gupta@intel.com>
Reviewed-by: Anshuman Gupta <anshuman.gupta@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
-rw-r--r-- | drivers/gpu/drm/xe/xe_pci.c | 54 | ||||
-rw-r--r-- | drivers/gpu/drm/xe/xe_pm.c | 11 |
2 files changed, 43 insertions, 22 deletions
diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c index 4cbacc80594b..6e31b596683e 100644 --- a/drivers/gpu/drm/xe/xe_pci.c +++ b/drivers/gpu/drm/xe/xe_pci.c @@ -30,6 +30,28 @@ enum toggle_d3cold { D3COLD_ENABLE, }; +static void d3cold_toggle(struct pci_dev *pdev, enum toggle_d3cold toggle) +{ + struct xe_device *xe = pdev_to_xe_device(pdev); + struct pci_dev *root_pdev; + + if (!xe->d3cold.capable) + return; + + root_pdev = pcie_find_root_port(pdev); + if (!root_pdev) + return; + + switch (toggle) { + case D3COLD_DISABLE: + pci_d3cold_disable(root_pdev); + break; + case D3COLD_ENABLE: + pci_d3cold_enable(root_pdev); + break; + } +} + struct xe_subplatform_desc { enum xe_subplatform subplatform; const char *name; @@ -697,6 +719,13 @@ static int xe_pci_suspend(struct device *dev) if (err) return err; + /* + * Enabling D3Cold is needed for S2Idle/S0ix. + * It is save to allow here since xe_pm_suspend has evicted + * the local memory and the direct complete optimization is disabled. + */ + d3cold_toggle(pdev, D3COLD_ENABLE); + pci_save_state(pdev); pci_disable_device(pdev); @@ -712,6 +741,9 @@ static int xe_pci_resume(struct device *dev) struct pci_dev *pdev = to_pci_dev(dev); int err; + /* Give back the D3Cold decision to the runtime P M*/ + d3cold_toggle(pdev, D3COLD_DISABLE); + err = pci_set_power_state(pdev, PCI_D0); if (err) return err; @@ -731,28 +763,6 @@ static int xe_pci_resume(struct device *dev) return 0; } -static void d3cold_toggle(struct pci_dev *pdev, enum toggle_d3cold toggle) -{ - struct xe_device *xe = pdev_to_xe_device(pdev); - struct pci_dev *root_pdev; - - if (!xe->d3cold.capable) - return; - - root_pdev = pcie_find_root_port(pdev); - if (!root_pdev) - return; - - switch (toggle) { - case D3COLD_DISABLE: - pci_d3cold_disable(root_pdev); - break; - case D3COLD_ENABLE: - pci_d3cold_enable(root_pdev); - break; - } -} - static int xe_pci_runtime_suspend(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); diff --git a/drivers/gpu/drm/xe/xe_pm.c b/drivers/gpu/drm/xe/xe_pm.c index a20a2fb34a7d..cdde0d87fd9f 100644 --- a/drivers/gpu/drm/xe/xe_pm.c +++ b/drivers/gpu/drm/xe/xe_pm.c @@ -128,6 +128,17 @@ static void xe_pm_runtime_init(struct xe_device *xe) { struct device *dev = xe->drm.dev; + /* + * Disable the system suspend direct complete optimization. + * We need to ensure that the regular device suspend/resume functions + * are called since our runtime_pm cannot guarantee local memory + * eviction for d3cold. + * TODO: Check HDA audio dependencies claimed by i915, and then enforce + * this option to integrated graphics as well. + */ + if (IS_DGFX(xe)) + dev_pm_set_driver_flags(dev, DPM_FLAG_NO_DIRECT_COMPLETE); + pm_runtime_use_autosuspend(dev); pm_runtime_set_autosuspend_delay(dev, 1000); pm_runtime_set_active(dev); |