summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRodrigo Vivi <rodrigo.vivi@intel.com>2023-07-26 01:11:59 +0300
committerRodrigo Vivi <rodrigo.vivi@intel.com>2023-12-21 19:39:16 +0300
commitd87c424afaf62f11ded6e66b4bdfbd5f5da8b330 (patch)
tree6d89a2cd52d179c729b2015a2f598781cbdf19c2
parenta32d82b4cfd63a9bc198bd9faa54844b8d04c5d3 (diff)
downloadlinux-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.c54
-rw-r--r--drivers/gpu/drm/xe/xe_pm.c11
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);