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 */ 91 bool xe_rpm_reclaim_safe(const struct xe_device *xe) 92 { 93 return !xe->d3cold.capable && !xe->info.has_sriov; 94 } 95 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 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 */ 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 */ 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 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 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 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 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 */ 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 */ 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 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 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 761 int __init xe_pm_module_init(void) 762 { 763 xe_pm_runtime_lockdep_prime(); 764 return 0; 765 } 766