1 // SPDX-License-Identifier: MIT
2 /*
3 * Copyright © 2022 Intel Corporation
4 */
5
6 #include "xe_pm.h"
7
8 #include <linux/fault-inject.h>
9 #include <linux/pm_runtime.h>
10 #include <linux/suspend.h>
11
12 #include <drm/drm_managed.h>
13 #include <drm/ttm/ttm_placement.h>
14
15 #include "display/xe_display.h"
16 #include "xe_bo.h"
17 #include "xe_bo_evict.h"
18 #include "xe_device.h"
19 #include "xe_device_sysfs.h"
20 #include "xe_ggtt.h"
21 #include "xe_gt.h"
22 #include "xe_guc.h"
23 #include "xe_irq.h"
24 #include "xe_pcode.h"
25 #include "xe_trace.h"
26 #include "xe_wa.h"
27
28 /**
29 * DOC: Xe Power Management
30 *
31 * Xe PM implements the main routines for both system level suspend states and
32 * for the opportunistic runtime suspend states.
33 *
34 * System Level Suspend (S-States) - In general this is OS initiated suspend
35 * driven by ACPI for achieving S0ix (a.k.a. S2idle, freeze), S3 (suspend to ram),
36 * S4 (disk). The main functions here are `xe_pm_suspend` and `xe_pm_resume`. They
37 * are the main point for the suspend to and resume from these states.
38 *
39 * PCI Device Suspend (D-States) - This is the opportunistic PCIe device low power
40 * state D3, controlled by the PCI subsystem and ACPI with the help from the
41 * runtime_pm infrastructure.
42 * PCI D3 is special and can mean D3hot, where Vcc power is on for keeping memory
43 * alive and quicker low latency resume or D3Cold where Vcc power is off for
44 * better power savings.
45 * The Vcc control of PCI hierarchy can only be controlled at the PCI root port
46 * level, while the device driver can be behind multiple bridges/switches and
47 * paired with other devices. For this reason, the PCI subsystem cannot perform
48 * the transition towards D3Cold. The lowest runtime PM possible from the PCI
49 * subsystem is D3hot. Then, if all these paired devices in the same root port
50 * are in D3hot, ACPI will assist here and run its own methods (_PR3 and _OFF)
51 * to perform the transition from D3hot to D3cold. Xe may disallow this
52 * transition by calling pci_d3cold_disable(root_pdev) before going to runtime
53 * suspend. It will be based on runtime conditions such as VRAM usage for a
54 * quick and low latency resume for instance.
55 *
56 * Runtime PM - This infrastructure provided by the Linux kernel allows the
57 * device drivers to indicate when the can be runtime suspended, so the device
58 * could be put at D3 (if supported), or allow deeper package sleep states
59 * (PC-states), and/or other low level power states. Xe PM component provides
60 * `xe_pm_runtime_suspend` and `xe_pm_runtime_resume` functions that PCI
61 * subsystem will call before transition to/from runtime suspend.
62 *
63 * Also, Xe PM provides get and put functions that Xe driver will use to
64 * indicate activity. In order to avoid locking complications with the memory
65 * management, whenever possible, these get and put functions needs to be called
66 * from the higher/outer levels.
67 * The main cases that need to be protected from the outer levels are: IOCTL,
68 * sysfs, debugfs, dma-buf sharing, GPU execution.
69 *
70 * This component is not responsible for GT idleness (RC6) nor GT frequency
71 * management (RPS).
72 */
73
74 #ifdef CONFIG_LOCKDEP
75 static struct lockdep_map xe_pm_runtime_d3cold_map = {
76 .name = "xe_rpm_d3cold_map"
77 };
78
79 static struct lockdep_map xe_pm_runtime_nod3cold_map = {
80 .name = "xe_rpm_nod3cold_map"
81 };
82 #endif
83
84 /**
85 * xe_rpm_reclaim_safe() - Whether runtime resume can be done from reclaim context
86 * @xe: The xe device.
87 *
88 * Return: true if it is safe to runtime resume from reclaim context.
89 * false otherwise.
90 */
xe_rpm_reclaim_safe(const struct xe_device * xe)91 bool xe_rpm_reclaim_safe(const struct xe_device *xe)
92 {
93 return !xe->d3cold.capable && !xe->info.has_sriov;
94 }
95
xe_rpm_lockmap_acquire(const struct xe_device * xe)96 static void xe_rpm_lockmap_acquire(const struct xe_device *xe)
97 {
98 lock_map_acquire(xe_rpm_reclaim_safe(xe) ?
99 &xe_pm_runtime_nod3cold_map :
100 &xe_pm_runtime_d3cold_map);
101 }
102
xe_rpm_lockmap_release(const struct xe_device * xe)103 static void xe_rpm_lockmap_release(const struct xe_device *xe)
104 {
105 lock_map_release(xe_rpm_reclaim_safe(xe) ?
106 &xe_pm_runtime_nod3cold_map :
107 &xe_pm_runtime_d3cold_map);
108 }
109
110 /**
111 * xe_pm_suspend - Helper for System suspend, i.e. S0->S3 / S0->S2idle
112 * @xe: xe device instance
113 *
114 * Return: 0 on success
115 */
xe_pm_suspend(struct xe_device * xe)116 int xe_pm_suspend(struct xe_device *xe)
117 {
118 struct xe_gt *gt;
119 u8 id;
120 int err;
121
122 drm_dbg(&xe->drm, "Suspending device\n");
123 trace_xe_pm_suspend(xe, __builtin_return_address(0));
124
125 for_each_gt(gt, xe, id)
126 xe_gt_suspend_prepare(gt);
127
128 xe_display_pm_suspend(xe);
129
130 /* FIXME: Super racey... */
131 err = xe_bo_evict_all(xe);
132 if (err)
133 goto err;
134
135 for_each_gt(gt, xe, id) {
136 err = xe_gt_suspend(gt);
137 if (err) {
138 xe_display_pm_resume(xe);
139 goto err;
140 }
141 }
142
143 xe_irq_suspend(xe);
144
145 xe_display_pm_suspend_late(xe);
146
147 drm_dbg(&xe->drm, "Device suspended\n");
148 return 0;
149 err:
150 drm_dbg(&xe->drm, "Device suspend failed %d\n", err);
151 return err;
152 }
153
154 /**
155 * xe_pm_resume - Helper for System resume S3->S0 / S2idle->S0
156 * @xe: xe device instance
157 *
158 * Return: 0 on success
159 */
xe_pm_resume(struct xe_device * xe)160 int xe_pm_resume(struct xe_device *xe)
161 {
162 struct xe_tile *tile;
163 struct xe_gt *gt;
164 u8 id;
165 int err;
166
167 drm_dbg(&xe->drm, "Resuming device\n");
168 trace_xe_pm_resume(xe, __builtin_return_address(0));
169
170 for_each_tile(tile, xe, id)
171 xe_wa_apply_tile_workarounds(tile);
172
173 err = xe_pcode_ready(xe, true);
174 if (err)
175 return err;
176
177 xe_display_pm_resume_early(xe);
178
179 /*
180 * This only restores pinned memory which is the memory required for the
181 * GT(s) to resume.
182 */
183 err = xe_bo_restore_kernel(xe);
184 if (err)
185 goto err;
186
187 xe_irq_resume(xe);
188
189 for_each_gt(gt, xe, id)
190 xe_gt_resume(gt);
191
192 xe_display_pm_resume(xe);
193
194 err = xe_bo_restore_user(xe);
195 if (err)
196 goto err;
197
198 drm_dbg(&xe->drm, "Device resumed\n");
199 return 0;
200 err:
201 drm_dbg(&xe->drm, "Device resume failed %d\n", err);
202 return err;
203 }
204
xe_pm_pci_d3cold_capable(struct xe_device * xe)205 static bool xe_pm_pci_d3cold_capable(struct xe_device *xe)
206 {
207 struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
208 struct pci_dev *root_pdev;
209
210 root_pdev = pcie_find_root_port(pdev);
211 if (!root_pdev)
212 return false;
213
214 /* D3Cold requires PME capability */
215 if (!pci_pme_capable(root_pdev, PCI_D3cold)) {
216 drm_dbg(&xe->drm, "d3cold: PME# not supported\n");
217 return false;
218 }
219
220 /* D3Cold requires _PR3 power resource */
221 if (!pci_pr3_present(root_pdev)) {
222 drm_dbg(&xe->drm, "d3cold: ACPI _PR3 not present\n");
223 return false;
224 }
225
226 return true;
227 }
228
xe_pm_runtime_init(struct xe_device * xe)229 static void xe_pm_runtime_init(struct xe_device *xe)
230 {
231 struct device *dev = xe->drm.dev;
232
233 /*
234 * Disable the system suspend direct complete optimization.
235 * We need to ensure that the regular device suspend/resume functions
236 * are called since our runtime_pm cannot guarantee local memory
237 * eviction for d3cold.
238 * TODO: Check HDA audio dependencies claimed by i915, and then enforce
239 * this option to integrated graphics as well.
240 */
241 if (IS_DGFX(xe))
242 dev_pm_set_driver_flags(dev, DPM_FLAG_NO_DIRECT_COMPLETE);
243
244 pm_runtime_use_autosuspend(dev);
245 pm_runtime_set_autosuspend_delay(dev, 1000);
246 pm_runtime_set_active(dev);
247 pm_runtime_allow(dev);
248 pm_runtime_mark_last_busy(dev);
249 pm_runtime_put(dev);
250 }
251
xe_pm_init_early(struct xe_device * xe)252 int xe_pm_init_early(struct xe_device *xe)
253 {
254 int err;
255
256 INIT_LIST_HEAD(&xe->mem_access.vram_userfault.list);
257
258 err = drmm_mutex_init(&xe->drm, &xe->mem_access.vram_userfault.lock);
259 if (err)
260 return err;
261
262 err = drmm_mutex_init(&xe->drm, &xe->d3cold.lock);
263 if (err)
264 return err;
265
266 return 0;
267 }
268 ALLOW_ERROR_INJECTION(xe_pm_init_early, ERRNO); /* See xe_pci_probe() */
269
vram_threshold_value(struct xe_device * xe)270 static u32 vram_threshold_value(struct xe_device *xe)
271 {
272 /* FIXME: D3Cold temporarily disabled by default on BMG */
273 if (xe->info.platform == XE_BATTLEMAGE)
274 return 0;
275
276 return DEFAULT_VRAM_THRESHOLD;
277 }
278
279 /**
280 * xe_pm_init - Initialize Xe Power Management
281 * @xe: xe device instance
282 *
283 * This component is responsible for System and Device sleep states.
284 *
285 * Returns 0 for success, negative error code otherwise.
286 */
xe_pm_init(struct xe_device * xe)287 int xe_pm_init(struct xe_device *xe)
288 {
289 u32 vram_threshold;
290 int err;
291
292 /* For now suspend/resume is only allowed with GuC */
293 if (!xe_device_uc_enabled(xe))
294 return 0;
295
296 xe->d3cold.capable = xe_pm_pci_d3cold_capable(xe);
297
298 if (xe->d3cold.capable) {
299 err = xe_device_sysfs_init(xe);
300 if (err)
301 return err;
302
303 vram_threshold = vram_threshold_value(xe);
304 err = xe_pm_set_vram_threshold(xe, vram_threshold);
305 if (err)
306 return err;
307 }
308
309 xe_pm_runtime_init(xe);
310
311 return 0;
312 }
313
314 /**
315 * xe_pm_runtime_fini - Finalize Runtime PM
316 * @xe: xe device instance
317 */
xe_pm_runtime_fini(struct xe_device * xe)318 void xe_pm_runtime_fini(struct xe_device *xe)
319 {
320 struct device *dev = xe->drm.dev;
321
322 pm_runtime_get_sync(dev);
323 pm_runtime_forbid(dev);
324 }
325
xe_pm_write_callback_task(struct xe_device * xe,struct task_struct * task)326 static void xe_pm_write_callback_task(struct xe_device *xe,
327 struct task_struct *task)
328 {
329 WRITE_ONCE(xe->pm_callback_task, task);
330
331 /*
332 * Just in case it's somehow possible for our writes to be reordered to
333 * the extent that something else re-uses the task written in
334 * pm_callback_task. For example after returning from the callback, but
335 * before the reordered write that resets pm_callback_task back to NULL.
336 */
337 smp_mb(); /* pairs with xe_pm_read_callback_task */
338 }
339
xe_pm_read_callback_task(struct xe_device * xe)340 struct task_struct *xe_pm_read_callback_task(struct xe_device *xe)
341 {
342 smp_mb(); /* pairs with xe_pm_write_callback_task */
343
344 return READ_ONCE(xe->pm_callback_task);
345 }
346
347 /**
348 * xe_pm_runtime_suspended - Check if runtime_pm state is suspended
349 * @xe: xe device instance
350 *
351 * This does not provide any guarantee that the device is going to remain
352 * suspended as it might be racing with the runtime state transitions.
353 * It can be used only as a non-reliable assertion, to ensure that we are not in
354 * the sleep state while trying to access some memory for instance.
355 *
356 * Returns true if PCI device is suspended, false otherwise.
357 */
xe_pm_runtime_suspended(struct xe_device * xe)358 bool xe_pm_runtime_suspended(struct xe_device *xe)
359 {
360 return pm_runtime_suspended(xe->drm.dev);
361 }
362
363 /**
364 * xe_pm_runtime_suspend - Prepare our device for D3hot/D3Cold
365 * @xe: xe device instance
366 *
367 * Returns 0 for success, negative error code otherwise.
368 */
xe_pm_runtime_suspend(struct xe_device * xe)369 int xe_pm_runtime_suspend(struct xe_device *xe)
370 {
371 struct xe_bo *bo, *on;
372 struct xe_gt *gt;
373 u8 id;
374 int err = 0;
375
376 trace_xe_pm_runtime_suspend(xe, __builtin_return_address(0));
377 /* Disable access_ongoing asserts and prevent recursive pm calls */
378 xe_pm_write_callback_task(xe, current);
379
380 /*
381 * The actual xe_pm_runtime_put() is always async underneath, so
382 * exactly where that is called should makes no difference to us. However
383 * we still need to be very careful with the locks that this callback
384 * acquires and the locks that are acquired and held by any callers of
385 * xe_runtime_pm_get(). We already have the matching annotation
386 * on that side, but we also need it here. For example lockdep should be
387 * able to tell us if the following scenario is in theory possible:
388 *
389 * CPU0 | CPU1 (kworker)
390 * lock(A) |
391 * | xe_pm_runtime_suspend()
392 * | lock(A)
393 * xe_pm_runtime_get() |
394 *
395 * This will clearly deadlock since rpm core needs to wait for
396 * xe_pm_runtime_suspend() to complete, but here we are holding lock(A)
397 * on CPU0 which prevents CPU1 making forward progress. With the
398 * annotation here and in xe_pm_runtime_get() lockdep will see
399 * the potential lock inversion and give us a nice splat.
400 */
401 xe_rpm_lockmap_acquire(xe);
402
403 /*
404 * Applying lock for entire list op as xe_ttm_bo_destroy and xe_bo_move_notify
405 * also checks and deletes bo entry from user fault list.
406 */
407 mutex_lock(&xe->mem_access.vram_userfault.lock);
408 list_for_each_entry_safe(bo, on,
409 &xe->mem_access.vram_userfault.list, vram_userfault_link)
410 xe_bo_runtime_pm_release_mmap_offset(bo);
411 mutex_unlock(&xe->mem_access.vram_userfault.lock);
412
413 xe_display_pm_runtime_suspend(xe);
414
415 if (xe->d3cold.allowed) {
416 err = xe_bo_evict_all(xe);
417 if (err)
418 goto out;
419 }
420
421 for_each_gt(gt, xe, id) {
422 err = xe_gt_suspend(gt);
423 if (err)
424 goto out;
425 }
426
427 xe_irq_suspend(xe);
428
429 xe_display_pm_runtime_suspend_late(xe);
430
431 out:
432 if (err)
433 xe_display_pm_runtime_resume(xe);
434 xe_rpm_lockmap_release(xe);
435 xe_pm_write_callback_task(xe, NULL);
436 return err;
437 }
438
439 /**
440 * xe_pm_runtime_resume - Waking up from D3hot/D3Cold
441 * @xe: xe device instance
442 *
443 * Returns 0 for success, negative error code otherwise.
444 */
xe_pm_runtime_resume(struct xe_device * xe)445 int xe_pm_runtime_resume(struct xe_device *xe)
446 {
447 struct xe_gt *gt;
448 u8 id;
449 int err = 0;
450
451 trace_xe_pm_runtime_resume(xe, __builtin_return_address(0));
452 /* Disable access_ongoing asserts and prevent recursive pm calls */
453 xe_pm_write_callback_task(xe, current);
454
455 xe_rpm_lockmap_acquire(xe);
456
457 if (xe->d3cold.allowed) {
458 err = xe_pcode_ready(xe, true);
459 if (err)
460 goto out;
461
462 xe_display_pm_resume_early(xe);
463
464 /*
465 * This only restores pinned memory which is the memory
466 * required for the GT(s) to resume.
467 */
468 err = xe_bo_restore_kernel(xe);
469 if (err)
470 goto out;
471 }
472
473 xe_irq_resume(xe);
474
475 for_each_gt(gt, xe, id)
476 xe_gt_resume(gt);
477
478 xe_display_pm_runtime_resume(xe);
479
480 if (xe->d3cold.allowed) {
481 err = xe_bo_restore_user(xe);
482 if (err)
483 goto out;
484 }
485
486 out:
487 xe_rpm_lockmap_release(xe);
488 xe_pm_write_callback_task(xe, NULL);
489 return err;
490 }
491
492 /*
493 * For places where resume is synchronous it can be quite easy to deadlock
494 * if we are not careful. Also in practice it might be quite timing
495 * sensitive to ever see the 0 -> 1 transition with the callers locks
496 * held, so deadlocks might exist but are hard for lockdep to ever see.
497 * With this in mind, help lockdep learn about the potentially scary
498 * stuff that can happen inside the runtime_resume callback by acquiring
499 * a dummy lock (it doesn't protect anything and gets compiled out on
500 * non-debug builds). Lockdep then only needs to see the
501 * xe_pm_runtime_xxx_map -> runtime_resume callback once, and then can
502 * hopefully validate all the (callers_locks) -> xe_pm_runtime_xxx_map.
503 * For example if the (callers_locks) are ever grabbed in the
504 * runtime_resume callback, lockdep should give us a nice splat.
505 */
xe_rpm_might_enter_cb(const struct xe_device * xe)506 static void xe_rpm_might_enter_cb(const struct xe_device *xe)
507 {
508 xe_rpm_lockmap_acquire(xe);
509 xe_rpm_lockmap_release(xe);
510 }
511
512 /*
513 * Prime the lockdep maps for known locking orders that need to
514 * be supported but that may not always occur on all systems.
515 */
xe_pm_runtime_lockdep_prime(void)516 static void xe_pm_runtime_lockdep_prime(void)
517 {
518 struct dma_resv lockdep_resv;
519
520 dma_resv_init(&lockdep_resv);
521 lock_map_acquire(&xe_pm_runtime_d3cold_map);
522 /* D3Cold takes the dma_resv locks to evict bos */
523 dma_resv_lock(&lockdep_resv, NULL);
524 dma_resv_unlock(&lockdep_resv);
525 lock_map_release(&xe_pm_runtime_d3cold_map);
526
527 /* Shrinkers might like to wake up the device under reclaim. */
528 fs_reclaim_acquire(GFP_KERNEL);
529 lock_map_acquire(&xe_pm_runtime_nod3cold_map);
530 lock_map_release(&xe_pm_runtime_nod3cold_map);
531 fs_reclaim_release(GFP_KERNEL);
532 }
533
534 /**
535 * xe_pm_runtime_get - Get a runtime_pm reference and resume synchronously
536 * @xe: xe device instance
537 */
xe_pm_runtime_get(struct xe_device * xe)538 void xe_pm_runtime_get(struct xe_device *xe)
539 {
540 trace_xe_pm_runtime_get(xe, __builtin_return_address(0));
541 pm_runtime_get_noresume(xe->drm.dev);
542
543 if (xe_pm_read_callback_task(xe) == current)
544 return;
545
546 xe_rpm_might_enter_cb(xe);
547 pm_runtime_resume(xe->drm.dev);
548 }
549
550 /**
551 * xe_pm_runtime_put - Put the runtime_pm reference back and mark as idle
552 * @xe: xe device instance
553 */
xe_pm_runtime_put(struct xe_device * xe)554 void xe_pm_runtime_put(struct xe_device *xe)
555 {
556 trace_xe_pm_runtime_put(xe, __builtin_return_address(0));
557 if (xe_pm_read_callback_task(xe) == current) {
558 pm_runtime_put_noidle(xe->drm.dev);
559 } else {
560 pm_runtime_mark_last_busy(xe->drm.dev);
561 pm_runtime_put(xe->drm.dev);
562 }
563 }
564
565 /**
566 * xe_pm_runtime_get_ioctl - Get a runtime_pm reference before ioctl
567 * @xe: xe device instance
568 *
569 * Returns: Any number greater than or equal to 0 for success, negative error
570 * code otherwise.
571 */
xe_pm_runtime_get_ioctl(struct xe_device * xe)572 int xe_pm_runtime_get_ioctl(struct xe_device *xe)
573 {
574 trace_xe_pm_runtime_get_ioctl(xe, __builtin_return_address(0));
575 if (WARN_ON(xe_pm_read_callback_task(xe) == current))
576 return -ELOOP;
577
578 xe_rpm_might_enter_cb(xe);
579 return pm_runtime_get_sync(xe->drm.dev);
580 }
581
582 /**
583 * xe_pm_runtime_get_if_active - Get a runtime_pm reference if device active
584 * @xe: xe device instance
585 *
586 * Return: True if device is awake (regardless the previous number of references)
587 * and a new reference was taken, false otherwise.
588 */
xe_pm_runtime_get_if_active(struct xe_device * xe)589 bool xe_pm_runtime_get_if_active(struct xe_device *xe)
590 {
591 return pm_runtime_get_if_active(xe->drm.dev) > 0;
592 }
593
594 /**
595 * xe_pm_runtime_get_if_in_use - Get a new reference if device is active with previous ref taken
596 * @xe: xe device instance
597 *
598 * Return: True if device is awake, a previous reference had been already taken,
599 * and a new reference was now taken, false otherwise.
600 */
xe_pm_runtime_get_if_in_use(struct xe_device * xe)601 bool xe_pm_runtime_get_if_in_use(struct xe_device *xe)
602 {
603 if (xe_pm_read_callback_task(xe) == current) {
604 /* The device is awake, grab the ref and move on */
605 pm_runtime_get_noresume(xe->drm.dev);
606 return true;
607 }
608
609 return pm_runtime_get_if_in_use(xe->drm.dev) > 0;
610 }
611
612 /*
613 * Very unreliable! Should only be used to suppress the false positive case
614 * in the missing outer rpm protection warning.
615 */
xe_pm_suspending_or_resuming(struct xe_device * xe)616 static bool xe_pm_suspending_or_resuming(struct xe_device *xe)
617 {
618 #ifdef CONFIG_PM
619 struct device *dev = xe->drm.dev;
620
621 return dev->power.runtime_status == RPM_SUSPENDING ||
622 dev->power.runtime_status == RPM_RESUMING ||
623 pm_suspend_target_state != PM_SUSPEND_ON;
624 #else
625 return false;
626 #endif
627 }
628
629 /**
630 * xe_pm_runtime_get_noresume - Bump runtime PM usage counter without resuming
631 * @xe: xe device instance
632 *
633 * This function should be used in inner places where it is surely already
634 * protected by outer-bound callers of `xe_pm_runtime_get`.
635 * It will warn if not protected.
636 * The reference should be put back after this function regardless, since it
637 * will always bump the usage counter, regardless.
638 */
xe_pm_runtime_get_noresume(struct xe_device * xe)639 void xe_pm_runtime_get_noresume(struct xe_device *xe)
640 {
641 bool ref;
642
643 ref = xe_pm_runtime_get_if_in_use(xe);
644
645 if (!ref) {
646 pm_runtime_get_noresume(xe->drm.dev);
647 drm_WARN(&xe->drm, !xe_pm_suspending_or_resuming(xe),
648 "Missing outer runtime PM protection\n");
649 }
650 }
651
652 /**
653 * xe_pm_runtime_resume_and_get - Resume, then get a runtime_pm ref if awake.
654 * @xe: xe device instance
655 *
656 * Returns: True if device is awake and the reference was taken, false otherwise.
657 */
xe_pm_runtime_resume_and_get(struct xe_device * xe)658 bool xe_pm_runtime_resume_and_get(struct xe_device *xe)
659 {
660 if (xe_pm_read_callback_task(xe) == current) {
661 /* The device is awake, grab the ref and move on */
662 pm_runtime_get_noresume(xe->drm.dev);
663 return true;
664 }
665
666 xe_rpm_might_enter_cb(xe);
667 return pm_runtime_resume_and_get(xe->drm.dev) >= 0;
668 }
669
670 /**
671 * xe_pm_assert_unbounded_bridge - Disable PM on unbounded pcie parent bridge
672 * @xe: xe device instance
673 */
xe_pm_assert_unbounded_bridge(struct xe_device * xe)674 void xe_pm_assert_unbounded_bridge(struct xe_device *xe)
675 {
676 struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
677 struct pci_dev *bridge = pci_upstream_bridge(pdev);
678
679 if (!bridge)
680 return;
681
682 if (!bridge->driver) {
683 drm_warn(&xe->drm, "unbounded parent pci bridge, device won't support any PM support.\n");
684 device_set_pm_not_required(&pdev->dev);
685 }
686 }
687
688 /**
689 * xe_pm_set_vram_threshold - Set a vram threshold for allowing/blocking D3Cold
690 * @xe: xe device instance
691 * @threshold: VRAM size in bites for the D3cold threshold
692 *
693 * Returns 0 for success, negative error code otherwise.
694 */
xe_pm_set_vram_threshold(struct xe_device * xe,u32 threshold)695 int xe_pm_set_vram_threshold(struct xe_device *xe, u32 threshold)
696 {
697 struct ttm_resource_manager *man;
698 u32 vram_total_mb = 0;
699 int i;
700
701 for (i = XE_PL_VRAM0; i <= XE_PL_VRAM1; ++i) {
702 man = ttm_manager_type(&xe->ttm, i);
703 if (man)
704 vram_total_mb += DIV_ROUND_UP_ULL(man->size, 1024 * 1024);
705 }
706
707 drm_dbg(&xe->drm, "Total vram %u mb\n", vram_total_mb);
708
709 if (threshold > vram_total_mb)
710 return -EINVAL;
711
712 mutex_lock(&xe->d3cold.lock);
713 xe->d3cold.vram_threshold = threshold;
714 mutex_unlock(&xe->d3cold.lock);
715
716 return 0;
717 }
718
719 /**
720 * xe_pm_d3cold_allowed_toggle - Check conditions to toggle d3cold.allowed
721 * @xe: xe device instance
722 *
723 * To be called during runtime_pm idle callback.
724 * Check for all the D3Cold conditions ahead of runtime suspend.
725 */
xe_pm_d3cold_allowed_toggle(struct xe_device * xe)726 void xe_pm_d3cold_allowed_toggle(struct xe_device *xe)
727 {
728 struct ttm_resource_manager *man;
729 u32 total_vram_used_mb = 0;
730 u64 vram_used;
731 int i;
732
733 if (!xe->d3cold.capable) {
734 xe->d3cold.allowed = false;
735 return;
736 }
737
738 for (i = XE_PL_VRAM0; i <= XE_PL_VRAM1; ++i) {
739 man = ttm_manager_type(&xe->ttm, i);
740 if (man) {
741 vram_used = ttm_resource_manager_usage(man);
742 total_vram_used_mb += DIV_ROUND_UP_ULL(vram_used, 1024 * 1024);
743 }
744 }
745
746 mutex_lock(&xe->d3cold.lock);
747
748 if (total_vram_used_mb < xe->d3cold.vram_threshold)
749 xe->d3cold.allowed = true;
750 else
751 xe->d3cold.allowed = false;
752
753 mutex_unlock(&xe->d3cold.lock);
754 }
755
756 /**
757 * xe_pm_module_init() - Perform xe_pm specific module initialization.
758 *
759 * Return: 0 on success. Currently doesn't fail.
760 */
xe_pm_module_init(void)761 int __init xe_pm_module_init(void)
762 {
763 xe_pm_runtime_lockdep_prime();
764 return 0;
765 }
766