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