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