Merge tag 'drm-next-2024-03-13' of https://gitlab.freedesktop.org/drm/kernel
[sfrench/cifs-2.6.git] / drivers / gpu / drm / xe / xe_pm.c
index dd110058bf74fdb49eedf1212e2d5ac07aa47a44..53b3b0b019acd85fe48e375005e9b36149edad13 100644 (file)
 #include <drm/drm_managed.h>
 #include <drm/ttm/ttm_placement.h>
 
+#include "display/xe_display.h"
 #include "xe_bo.h"
 #include "xe_bo_evict.h"
 #include "xe_device.h"
 #include "xe_device_sysfs.h"
-#include "xe_display.h"
 #include "xe_ggtt.h"
 #include "xe_gt.h"
 #include "xe_guc.h"
@@ -125,17 +125,26 @@ int xe_pm_resume(struct xe_device *xe)
        return 0;
 }
 
-static bool xe_pm_pci_d3cold_capable(struct pci_dev *pdev)
+static bool xe_pm_pci_d3cold_capable(struct xe_device *xe)
 {
+       struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
        struct pci_dev *root_pdev;
 
        root_pdev = pcie_find_root_port(pdev);
        if (!root_pdev)
                return false;
 
-       /* D3Cold requires PME capability and _PR3 power resource */
-       if (!pci_pme_capable(root_pdev, PCI_D3cold) || !pci_pr3_present(root_pdev))
+       /* D3Cold requires PME capability */
+       if (!pci_pme_capable(root_pdev, PCI_D3cold)) {
+               drm_dbg(&xe->drm, "d3cold: PME# not supported\n");
                return false;
+       }
+
+       /* D3Cold requires _PR3 power resource */
+       if (!pci_pr3_present(root_pdev)) {
+               drm_dbg(&xe->drm, "d3cold: ACPI _PR3 not present\n");
+               return false;
+       }
 
        return true;
 }
@@ -163,17 +172,21 @@ static void xe_pm_runtime_init(struct xe_device *xe)
        pm_runtime_put(dev);
 }
 
-void xe_pm_init(struct xe_device *xe)
+void xe_pm_init_early(struct xe_device *xe)
 {
-       struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
+       INIT_LIST_HEAD(&xe->mem_access.vram_userfault.list);
+       drmm_mutex_init(&xe->drm, &xe->mem_access.vram_userfault.lock);
+}
 
+void xe_pm_init(struct xe_device *xe)
+{
        /* For now suspend/resume is only allowed with GuC */
        if (!xe_device_uc_enabled(xe))
                return;
 
        drmm_mutex_init(&xe->drm, &xe->d3cold.lock);
 
-       xe->d3cold.capable = xe_pm_pci_d3cold_capable(pdev);
+       xe->d3cold.capable = xe_pm_pci_d3cold_capable(xe);
 
        if (xe->d3cold.capable) {
                xe_device_sysfs_init(xe);
@@ -214,6 +227,7 @@ struct task_struct *xe_pm_read_callback_task(struct xe_device *xe)
 
 int xe_pm_runtime_suspend(struct xe_device *xe)
 {
+       struct xe_bo *bo, *on;
        struct xe_gt *gt;
        u8 id;
        int err = 0;
@@ -247,6 +261,16 @@ int xe_pm_runtime_suspend(struct xe_device *xe)
         */
        lock_map_acquire(&xe_device_mem_access_lockdep_map);
 
+       /*
+        * Applying lock for entire list op as xe_ttm_bo_destroy and xe_bo_move_notify
+        * also checks and delets bo entry from user fault list.
+        */
+       mutex_lock(&xe->mem_access.vram_userfault.lock);
+       list_for_each_entry_safe(bo, on,
+                                &xe->mem_access.vram_userfault.list, vram_userfault_link)
+               xe_bo_runtime_pm_release_mmap_offset(bo);
+       mutex_unlock(&xe->mem_access.vram_userfault.lock);
+
        if (xe->d3cold.allowed) {
                err = xe_bo_evict_all(xe);
                if (err)