| /* |
| * |
| * (C) COPYRIGHT 2015, 2017 ARM Limited. All rights reserved. |
| * |
| * This program is free software and is provided to you under the terms of the |
| * GNU General Public License version 2 as published by the Free Software |
| * Foundation, and any use by you of this program is subject to the terms |
| * of such GNU licence. |
| * |
| * A copy of the licence is included with the program, and can also be obtained |
| * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| * Boston, MA 02110-1301, USA. |
| * |
| */ |
| |
| |
| |
| #include <mali_kbase.h> |
| #include <mali_kbase_defs.h> |
| #include <linux/pm_runtime.h> |
| #include "mali_kbase_config_platform.h" |
| |
| inline int kbase_platform_dvfs_event(struct kbase_device *kbdev, u32 utilisation, |
| u32 util_gl_share, u32 util_cl_share[2]) |
| { |
| return 1; |
| } |
| |
| static int pm_callback_power_on(struct kbase_device *kbdev) |
| { |
| int ret = 1; /* Assume GPU has been powered off */ |
| int error; |
| |
| dev_dbg(kbdev->dev, "pm_callback_power_on %p\n", |
| (void *)kbdev->dev->pm_domain); |
| |
| error = pm_runtime_get_sync(kbdev->dev); |
| if (error == 1) { |
| /* |
| * Let core know that the chip has not been |
| * powered off, so we can save on re-initialization. |
| */ |
| ret = 0; |
| } |
| |
| dev_dbg(kbdev->dev, "pm_runtime_get_sync returned %d\n", error); |
| |
| return ret; |
| } |
| |
| static void pm_callback_power_off(struct kbase_device *kbdev) |
| { |
| dev_dbg(kbdev->dev, "pm_callback_power_off\n"); |
| |
| pm_runtime_mark_last_busy(kbdev->dev); |
| pm_runtime_put_autosuspend(kbdev->dev); |
| } |
| |
| #ifdef KBASE_PM_RUNTIME |
| static int kbase_device_runtime_init(struct kbase_device *kbdev) |
| { |
| int ret = 0; |
| |
| dev_dbg(kbdev->dev, "kbase_device_runtime_init\n"); |
| |
| pm_runtime_set_autosuspend_delay(kbdev->dev, AUTO_SUSPEND_DELAY); |
| pm_runtime_use_autosuspend(kbdev->dev); |
| |
| pm_runtime_set_active(kbdev->dev); |
| pm_runtime_enable(kbdev->dev); |
| |
| if (!pm_runtime_enabled(kbdev->dev)) { |
| dev_warn(kbdev->dev, "pm_runtime not enabled"); |
| ret = -ENOSYS; |
| } |
| |
| return ret; |
| } |
| |
| static void kbase_device_runtime_disable(struct kbase_device *kbdev) |
| { |
| dev_dbg(kbdev->dev, "kbase_device_runtime_disable\n"); |
| pm_runtime_disable(kbdev->dev); |
| } |
| #endif |
| |
| static int pm_callback_runtime_on(struct kbase_device *kbdev) |
| { |
| dev_dbg(kbdev->dev, "pm_callback_runtime_on\n"); |
| |
| return 0; |
| } |
| |
| static void pm_callback_runtime_off(struct kbase_device *kbdev) |
| { |
| dev_dbg(kbdev->dev, "pm_callback_runtime_off\n"); |
| } |
| |
| static void pm_callback_resume(struct kbase_device *kbdev) |
| { |
| int ret = pm_callback_runtime_on(kbdev); |
| |
| WARN_ON(ret); |
| } |
| |
| static void pm_callback_suspend(struct kbase_device *kbdev) |
| { |
| pm_callback_runtime_off(kbdev); |
| } |
| |
| struct kbase_pm_callback_conf pm_callbacks = { |
| .power_on_callback = pm_callback_power_on, |
| .power_off_callback = pm_callback_power_off, |
| .power_suspend_callback = pm_callback_suspend, |
| .power_resume_callback = pm_callback_resume, |
| #ifdef KBASE_PM_RUNTIME |
| .power_runtime_init_callback = kbase_device_runtime_init, |
| .power_runtime_term_callback = kbase_device_runtime_disable, |
| .power_runtime_on_callback = pm_callback_runtime_on, |
| .power_runtime_off_callback = pm_callback_runtime_off, |
| #else /* KBASE_PM_RUNTIME */ |
| .power_runtime_init_callback = NULL, |
| .power_runtime_term_callback = NULL, |
| .power_runtime_on_callback = NULL, |
| .power_runtime_off_callback = NULL, |
| #endif /* KBASE_PM_RUNTIME */ |
| }; |
| |
| |