xref: /linux/drivers/accel/amdxdna/amdxdna_pm.c (revision f6e8dc9edf963dbc99085e54f6ced6da9daa6100)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2025, Advanced Micro Devices, Inc.
4  */
5 
6 #include <drm/amdxdna_accel.h>
7 #include <drm/drm_drv.h>
8 #include <linux/pm_runtime.h>
9 
10 #include "amdxdna_pm.h"
11 
12 #define AMDXDNA_AUTOSUSPEND_DELAY	5000 /* milliseconds */
13 
14 int amdxdna_pm_suspend(struct device *dev)
15 {
16 	struct amdxdna_dev *xdna = to_xdna_dev(dev_get_drvdata(dev));
17 	int ret = -EOPNOTSUPP;
18 	bool rpm;
19 
20 	if (xdna->dev_info->ops->suspend) {
21 		rpm = xdna->rpm_on;
22 		xdna->rpm_on = false;
23 		ret = xdna->dev_info->ops->suspend(xdna);
24 		xdna->rpm_on = rpm;
25 	}
26 
27 	XDNA_DBG(xdna, "Suspend done ret %d", ret);
28 	return ret;
29 }
30 
31 int amdxdna_pm_resume(struct device *dev)
32 {
33 	struct amdxdna_dev *xdna = to_xdna_dev(dev_get_drvdata(dev));
34 	int ret = -EOPNOTSUPP;
35 	bool rpm;
36 
37 	if (xdna->dev_info->ops->resume) {
38 		rpm = xdna->rpm_on;
39 		xdna->rpm_on = false;
40 		ret = xdna->dev_info->ops->resume(xdna);
41 		xdna->rpm_on = rpm;
42 	}
43 
44 	XDNA_DBG(xdna, "Resume done ret %d", ret);
45 	return ret;
46 }
47 
48 int amdxdna_pm_resume_get(struct amdxdna_dev *xdna)
49 {
50 	struct device *dev = xdna->ddev.dev;
51 	int ret;
52 
53 	if (!xdna->rpm_on)
54 		return 0;
55 
56 	ret = pm_runtime_resume_and_get(dev);
57 	if (ret) {
58 		XDNA_ERR(xdna, "Resume failed: %d", ret);
59 		pm_runtime_set_suspended(dev);
60 	}
61 
62 	return ret;
63 }
64 
65 void amdxdna_pm_suspend_put(struct amdxdna_dev *xdna)
66 {
67 	struct device *dev = xdna->ddev.dev;
68 
69 	if (!xdna->rpm_on)
70 		return;
71 
72 	pm_runtime_put_autosuspend(dev);
73 }
74 
75 void amdxdna_pm_init(struct amdxdna_dev *xdna)
76 {
77 	struct device *dev = xdna->ddev.dev;
78 
79 	pm_runtime_set_active(dev);
80 	pm_runtime_set_autosuspend_delay(dev, AMDXDNA_AUTOSUSPEND_DELAY);
81 	pm_runtime_use_autosuspend(dev);
82 	pm_runtime_allow(dev);
83 	pm_runtime_put_autosuspend(dev);
84 	xdna->rpm_on = true;
85 }
86 
87 void amdxdna_pm_fini(struct amdxdna_dev *xdna)
88 {
89 	struct device *dev = xdna->ddev.dev;
90 
91 	xdna->rpm_on = false;
92 	pm_runtime_get_noresume(dev);
93 	pm_runtime_forbid(dev);
94 }
95