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