summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/xe/xe_pm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/xe/xe_pm.c')
-rw-r--r--drivers/gpu/drm/xe/xe_pm.c50
1 files changed, 30 insertions, 20 deletions
diff --git a/drivers/gpu/drm/xe/xe_pm.c b/drivers/gpu/drm/xe/xe_pm.c
index 37fbeda12d3b..9f3c14fd9f33 100644
--- a/drivers/gpu/drm/xe/xe_pm.c
+++ b/drivers/gpu/drm/xe/xe_pm.c
@@ -20,6 +20,7 @@
#include "xe_guc.h"
#include "xe_irq.h"
#include "xe_pcode.h"
+#include "xe_trace.h"
#include "xe_wa.h"
/**
@@ -69,7 +70,7 @@
*/
#ifdef CONFIG_LOCKDEP
-struct lockdep_map xe_pm_runtime_lockdep_map = {
+static struct lockdep_map xe_pm_runtime_lockdep_map = {
.name = "xe_pm_runtime_lockdep_map"
};
#endif
@@ -87,6 +88,7 @@ int xe_pm_suspend(struct xe_device *xe)
int err;
drm_dbg(&xe->drm, "Suspending device\n");
+ trace_xe_pm_suspend(xe, __builtin_return_address(0));
for_each_gt(gt, xe, id)
xe_gt_suspend_prepare(gt);
@@ -96,12 +98,12 @@ int xe_pm_suspend(struct xe_device *xe)
if (err)
goto err;
- xe_display_pm_suspend(xe);
+ xe_display_pm_suspend(xe, false);
for_each_gt(gt, xe, id) {
err = xe_gt_suspend(gt);
if (err) {
- xe_display_pm_resume(xe);
+ xe_display_pm_resume(xe, false);
goto err;
}
}
@@ -131,6 +133,7 @@ int xe_pm_resume(struct xe_device *xe)
int err;
drm_dbg(&xe->drm, "Resuming device\n");
+ trace_xe_pm_resume(xe, __builtin_return_address(0));
for_each_tile(tile, xe, id)
xe_wa_apply_tile_workarounds(tile);
@@ -151,7 +154,7 @@ int xe_pm_resume(struct xe_device *xe)
xe_irq_resume(xe);
- xe_display_pm_resume(xe);
+ xe_display_pm_resume(xe, false);
for_each_gt(gt, xe, id)
xe_gt_resume(gt);
@@ -326,6 +329,7 @@ int xe_pm_runtime_suspend(struct xe_device *xe)
u8 id;
int err = 0;
+ trace_xe_pm_runtime_suspend(xe, __builtin_return_address(0));
/* Disable access_ongoing asserts and prevent recursive pm calls */
xe_pm_write_callback_task(xe, current);
@@ -366,6 +370,7 @@ int xe_pm_runtime_suspend(struct xe_device *xe)
err = xe_bo_evict_all(xe);
if (err)
goto out;
+ xe_display_pm_suspend(xe, true);
}
for_each_gt(gt, xe, id) {
@@ -375,7 +380,12 @@ int xe_pm_runtime_suspend(struct xe_device *xe)
}
xe_irq_suspend(xe);
+
+ if (xe->d3cold.allowed)
+ xe_display_pm_suspend_late(xe);
out:
+ if (err)
+ xe_display_pm_resume(xe, true);
lock_map_release(&xe_pm_runtime_lockdep_map);
xe_pm_write_callback_task(xe, NULL);
return err;
@@ -393,24 +403,19 @@ int xe_pm_runtime_resume(struct xe_device *xe)
u8 id;
int err = 0;
+ trace_xe_pm_runtime_resume(xe, __builtin_return_address(0));
/* Disable access_ongoing asserts and prevent recursive pm calls */
xe_pm_write_callback_task(xe, current);
lock_map_acquire(&xe_pm_runtime_lockdep_map);
- /*
- * It can be possible that xe has allowed d3cold but other pcie devices
- * in gfx card soc would have blocked d3cold, therefore card has not
- * really lost power. Detecting primary Gt power is sufficient.
- */
- gt = xe_device_get_gt(xe, 0);
- xe->d3cold.power_lost = xe_guc_in_reset(&gt->uc.guc);
-
- if (xe->d3cold.allowed && xe->d3cold.power_lost) {
+ if (xe->d3cold.allowed) {
err = xe_pcode_ready(xe, true);
if (err)
goto out;
+ xe_display_pm_resume_early(xe);
+
/*
* This only restores pinned memory which is the memory
* required for the GT(s) to resume.
@@ -425,7 +430,8 @@ int xe_pm_runtime_resume(struct xe_device *xe)
for_each_gt(gt, xe, id)
xe_gt_resume(gt);
- if (xe->d3cold.allowed && xe->d3cold.power_lost) {
+ if (xe->d3cold.allowed) {
+ xe_display_pm_resume(xe, true);
err = xe_bo_restore_user(xe);
if (err)
goto out;
@@ -462,6 +468,7 @@ static void pm_runtime_lockdep_prime(void)
*/
void xe_pm_runtime_get(struct xe_device *xe)
{
+ trace_xe_pm_runtime_get(xe, __builtin_return_address(0));
pm_runtime_get_noresume(xe->drm.dev);
if (xe_pm_read_callback_task(xe) == current)
@@ -477,6 +484,7 @@ void xe_pm_runtime_get(struct xe_device *xe)
*/
void xe_pm_runtime_put(struct xe_device *xe)
{
+ trace_xe_pm_runtime_put(xe, __builtin_return_address(0));
if (xe_pm_read_callback_task(xe) == current) {
pm_runtime_put_noidle(xe->drm.dev);
} else {
@@ -494,6 +502,7 @@ void xe_pm_runtime_put(struct xe_device *xe)
*/
int xe_pm_runtime_get_ioctl(struct xe_device *xe)
{
+ trace_xe_pm_runtime_get_ioctl(xe, __builtin_return_address(0));
if (WARN_ON(xe_pm_read_callback_task(xe) == current))
return -ELOOP;
@@ -505,19 +514,20 @@ int xe_pm_runtime_get_ioctl(struct xe_device *xe)
* xe_pm_runtime_get_if_active - Get a runtime_pm reference if device active
* @xe: xe device instance
*
- * Returns: Any number greater than or equal to 0 for success, negative error
- * code otherwise.
+ * Return: True if device is awake (regardless the previous number of references)
+ * and a new reference was taken, false otherwise.
*/
-int xe_pm_runtime_get_if_active(struct xe_device *xe)
+bool xe_pm_runtime_get_if_active(struct xe_device *xe)
{
- return pm_runtime_get_if_active(xe->drm.dev);
+ return pm_runtime_get_if_active(xe->drm.dev) > 0;
}
/**
- * xe_pm_runtime_get_if_in_use - Get a runtime_pm reference and resume if needed
+ * xe_pm_runtime_get_if_in_use - Get a new reference if device is active with previous ref taken
* @xe: xe device instance
*
- * Returns: True if device is awake and the reference was taken, false otherwise.
+ * Return: True if device is awake, a previous reference had been already taken,
+ * and a new reference was now taken, false otherwise.
*/
bool xe_pm_runtime_get_if_in_use(struct xe_device *xe)
{