1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * (C) COPYRIGHT 2010-2022 ARM Limited. All rights reserved. 5*4882a593Smuzhiyun * 6*4882a593Smuzhiyun * This program is free software and is provided to you under the terms of the 7*4882a593Smuzhiyun * GNU General Public License version 2 as published by the Free Software 8*4882a593Smuzhiyun * Foundation, and any use by you of this program is subject to the terms 9*4882a593Smuzhiyun * of such GNU license. 10*4882a593Smuzhiyun * 11*4882a593Smuzhiyun * This program is distributed in the hope that it will be useful, 12*4882a593Smuzhiyun * but WITHOUT ANY WARRANTY; without even the implied warranty of 13*4882a593Smuzhiyun * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*4882a593Smuzhiyun * GNU General Public License for more details. 15*4882a593Smuzhiyun * 16*4882a593Smuzhiyun * You should have received a copy of the GNU General Public License 17*4882a593Smuzhiyun * along with this program; if not, you can access it online at 18*4882a593Smuzhiyun * http://www.gnu.org/licenses/gpl-2.0.html. 19*4882a593Smuzhiyun * 20*4882a593Smuzhiyun */ 21*4882a593Smuzhiyun 22*4882a593Smuzhiyun /** 23*4882a593Smuzhiyun * DOC: Power management API definitions 24*4882a593Smuzhiyun */ 25*4882a593Smuzhiyun 26*4882a593Smuzhiyun #ifndef _KBASE_PM_H_ 27*4882a593Smuzhiyun #define _KBASE_PM_H_ 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun #include "mali_kbase_hwaccess_pm.h" 30*4882a593Smuzhiyun 31*4882a593Smuzhiyun #define PM_ENABLE_IRQS 0x01 32*4882a593Smuzhiyun #define PM_HW_ISSUES_DETECT 0x02 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun #ifdef CONFIG_MALI_ARBITER_SUPPORT 35*4882a593Smuzhiyun /* In the case that the GPU was granted by the Arbiter, it will have 36*4882a593Smuzhiyun * already been reset. The following flag ensures it is not reset 37*4882a593Smuzhiyun * twice. 38*4882a593Smuzhiyun */ 39*4882a593Smuzhiyun #define PM_NO_RESET 0x04 40*4882a593Smuzhiyun #endif 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun /** 43*4882a593Smuzhiyun * kbase_pm_init - Initialize the power management framework. 44*4882a593Smuzhiyun * 45*4882a593Smuzhiyun * @kbdev: The kbase device structure for the device 46*4882a593Smuzhiyun * (must be a valid pointer) 47*4882a593Smuzhiyun * 48*4882a593Smuzhiyun * Must be called before any other power management function 49*4882a593Smuzhiyun * 50*4882a593Smuzhiyun * Return: 0 if the power management framework was successfully initialized. 51*4882a593Smuzhiyun */ 52*4882a593Smuzhiyun int kbase_pm_init(struct kbase_device *kbdev); 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun /** 55*4882a593Smuzhiyun * kbase_pm_powerup - Power up GPU after all modules have been initialized 56*4882a593Smuzhiyun * and interrupt handlers installed. 57*4882a593Smuzhiyun * 58*4882a593Smuzhiyun * @kbdev: The kbase device structure for the device (must be a valid pointer) 59*4882a593Smuzhiyun * @flags: Flags to pass on to kbase_pm_init_hw 60*4882a593Smuzhiyun * 61*4882a593Smuzhiyun * Return: 0 if powerup was successful. 62*4882a593Smuzhiyun */ 63*4882a593Smuzhiyun int kbase_pm_powerup(struct kbase_device *kbdev, unsigned int flags); 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun /** 66*4882a593Smuzhiyun * kbase_pm_halt - Halt the power management framework. 67*4882a593Smuzhiyun * 68*4882a593Smuzhiyun * @kbdev: The kbase device structure for the device (must be a valid pointer) 69*4882a593Smuzhiyun * 70*4882a593Smuzhiyun * Should ensure that no new interrupts are generated, 71*4882a593Smuzhiyun * but allow any currently running interrupt handlers to complete successfully. 72*4882a593Smuzhiyun * The GPU is forced off by the time this function returns, regardless of 73*4882a593Smuzhiyun * whether or not the active power policy asks for the GPU to be powered off. 74*4882a593Smuzhiyun */ 75*4882a593Smuzhiyun void kbase_pm_halt(struct kbase_device *kbdev); 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun /** 78*4882a593Smuzhiyun * kbase_pm_term - Terminate the power management framework. 79*4882a593Smuzhiyun * 80*4882a593Smuzhiyun * @kbdev: The kbase device structure for the device (must be a valid pointer) 81*4882a593Smuzhiyun * 82*4882a593Smuzhiyun * No power management functions may be called after this 83*4882a593Smuzhiyun * (except @ref kbase_pm_init) 84*4882a593Smuzhiyun */ 85*4882a593Smuzhiyun void kbase_pm_term(struct kbase_device *kbdev); 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun /** 88*4882a593Smuzhiyun * kbase_pm_context_active - Increment the count of active contexts. 89*4882a593Smuzhiyun * 90*4882a593Smuzhiyun * @kbdev: The kbase device structure for the device (must be a valid pointer) 91*4882a593Smuzhiyun * 92*4882a593Smuzhiyun * This function should be called when a context is about to submit a job. 93*4882a593Smuzhiyun * It informs the active power policy that the GPU is going to be in use shortly 94*4882a593Smuzhiyun * and the policy is expected to start turning on the GPU. 95*4882a593Smuzhiyun * 96*4882a593Smuzhiyun * This function will block until the GPU is available. 97*4882a593Smuzhiyun * 98*4882a593Smuzhiyun * This function ASSERTS if a suspend is occuring/has occurred whilst this is 99*4882a593Smuzhiyun * in use. Use kbase_pm_contect_active_unless_suspending() instead. 100*4882a593Smuzhiyun * 101*4882a593Smuzhiyun * @note a Suspend is only visible to Kernel threads; user-space threads in a 102*4882a593Smuzhiyun * syscall cannot witness a suspend, because they are frozen before the suspend 103*4882a593Smuzhiyun * begins. 104*4882a593Smuzhiyun */ 105*4882a593Smuzhiyun void kbase_pm_context_active(struct kbase_device *kbdev); 106*4882a593Smuzhiyun 107*4882a593Smuzhiyun 108*4882a593Smuzhiyun /** Handler codes for doing kbase_pm_context_active_handle_suspend() */ 109*4882a593Smuzhiyun enum kbase_pm_suspend_handler { 110*4882a593Smuzhiyun /** A suspend is not expected/not possible - this is the same as 111*4882a593Smuzhiyun * kbase_pm_context_active() 112*4882a593Smuzhiyun */ 113*4882a593Smuzhiyun KBASE_PM_SUSPEND_HANDLER_NOT_POSSIBLE, 114*4882a593Smuzhiyun /** If we're suspending, fail and don't increase the active count */ 115*4882a593Smuzhiyun KBASE_PM_SUSPEND_HANDLER_DONT_INCREASE, 116*4882a593Smuzhiyun /** If we're suspending, succeed and allow the active count to increase 117*4882a593Smuzhiyun * if it didn't go from 0->1 (i.e., we didn't re-activate the GPU). 118*4882a593Smuzhiyun * 119*4882a593Smuzhiyun * This should only be used when there is a bounded time on the activation 120*4882a593Smuzhiyun * (e.g. guarantee it's going to be idled very soon after) 121*4882a593Smuzhiyun */ 122*4882a593Smuzhiyun KBASE_PM_SUSPEND_HANDLER_DONT_REACTIVATE, 123*4882a593Smuzhiyun #ifdef CONFIG_MALI_ARBITER_SUPPORT 124*4882a593Smuzhiyun /** Special case when Arbiter has notified we can use GPU. 125*4882a593Smuzhiyun * Active count should always start at 0 in this case. 126*4882a593Smuzhiyun */ 127*4882a593Smuzhiyun KBASE_PM_SUSPEND_HANDLER_VM_GPU_GRANTED, 128*4882a593Smuzhiyun #endif /* CONFIG_MALI_ARBITER_SUPPORT */ 129*4882a593Smuzhiyun }; 130*4882a593Smuzhiyun 131*4882a593Smuzhiyun /** 132*4882a593Smuzhiyun * kbase_pm_context_active_handle_suspend - Suspend 'safe' variant of kbase_pm_context_active() 133*4882a593Smuzhiyun * 134*4882a593Smuzhiyun * @kbdev: The kbase device structure for the device (must be a valid pointer) 135*4882a593Smuzhiyun * @suspend_handler: The handler code for how to handle a suspend that might occur 136*4882a593Smuzhiyun * 137*4882a593Smuzhiyun * If a suspend is in progress, this allows for various different ways of 138*4882a593Smuzhiyun * handling the suspend. Refer to @ref enum kbase_pm_suspend_handler for details. 139*4882a593Smuzhiyun * 140*4882a593Smuzhiyun * We returns a status code indicating whether we're allowed to keep the GPU 141*4882a593Smuzhiyun * active during the suspend, depending on the handler code. If the status code 142*4882a593Smuzhiyun * indicates a failure, the caller must abort whatever operation it was 143*4882a593Smuzhiyun * attempting, and potentially queue it up for after the OS has resumed. 144*4882a593Smuzhiyun * 145*4882a593Smuzhiyun * Return: 0 on success, non-zero othrewise. 146*4882a593Smuzhiyun */ 147*4882a593Smuzhiyun int kbase_pm_context_active_handle_suspend(struct kbase_device *kbdev, enum kbase_pm_suspend_handler suspend_handler); 148*4882a593Smuzhiyun 149*4882a593Smuzhiyun /** 150*4882a593Smuzhiyun * kbase_pm_context_idle - Decrement the reference count of active contexts. 151*4882a593Smuzhiyun * 152*4882a593Smuzhiyun * @kbdev: The kbase device structure for the device (must be a valid pointer) 153*4882a593Smuzhiyun * 154*4882a593Smuzhiyun * This function should be called when a context becomes idle. 155*4882a593Smuzhiyun * After this call the GPU may be turned off by the power policy so the calling 156*4882a593Smuzhiyun * code should ensure that it does not access the GPU's registers. 157*4882a593Smuzhiyun */ 158*4882a593Smuzhiyun void kbase_pm_context_idle(struct kbase_device *kbdev); 159*4882a593Smuzhiyun 160*4882a593Smuzhiyun /* NOTE: kbase_pm_is_active() is in mali_kbase.h, because it is an inline 161*4882a593Smuzhiyun * function 162*4882a593Smuzhiyun */ 163*4882a593Smuzhiyun 164*4882a593Smuzhiyun /** 165*4882a593Smuzhiyun * kbase_pm_suspend - Suspend the GPU and prevent any further register accesses 166*4882a593Smuzhiyun * to it from Kernel threads. 167*4882a593Smuzhiyun * 168*4882a593Smuzhiyun * @kbdev: The kbase device structure for the device (must be a valid pointer) 169*4882a593Smuzhiyun * 170*4882a593Smuzhiyun * This is called in response to an OS suspend event, and calls into the various 171*4882a593Smuzhiyun * kbase components to complete the suspend. 172*4882a593Smuzhiyun * 173*4882a593Smuzhiyun * @note the mechanisms used here rely on all user-space threads being frozen 174*4882a593Smuzhiyun * by the OS before we suspend. Otherwise, an IOCTL could occur that powers up 175*4882a593Smuzhiyun * the GPU e.g. via atom submission. 176*4882a593Smuzhiyun * 177*4882a593Smuzhiyun * Return: 0 on success. 178*4882a593Smuzhiyun */ 179*4882a593Smuzhiyun int kbase_pm_suspend(struct kbase_device *kbdev); 180*4882a593Smuzhiyun 181*4882a593Smuzhiyun /** 182*4882a593Smuzhiyun * kbase_pm_resume - Resume the GPU, allow register accesses to it, 183*4882a593Smuzhiyun * and resume running atoms on the GPU. 184*4882a593Smuzhiyun * 185*4882a593Smuzhiyun * @kbdev: The kbase device structure for the device (must be a valid pointer) 186*4882a593Smuzhiyun * 187*4882a593Smuzhiyun * This is called in response to an OS resume event, and calls into the various 188*4882a593Smuzhiyun * kbase components to complete the resume. 189*4882a593Smuzhiyun * 190*4882a593Smuzhiyun * Also called when using VM arbiter, when GPU access has been granted. 191*4882a593Smuzhiyun */ 192*4882a593Smuzhiyun void kbase_pm_resume(struct kbase_device *kbdev); 193*4882a593Smuzhiyun 194*4882a593Smuzhiyun /** 195*4882a593Smuzhiyun * kbase_pm_vsync_callback - vsync callback 196*4882a593Smuzhiyun * 197*4882a593Smuzhiyun * @buffer_updated: 1 if a new frame was displayed, 0 otherwise 198*4882a593Smuzhiyun * @data: Pointer to the kbase device as returned by kbase_find_device() 199*4882a593Smuzhiyun * 200*4882a593Smuzhiyun * Callback function used to notify the power management code that a vsync has 201*4882a593Smuzhiyun * occurred on the display. 202*4882a593Smuzhiyun */ 203*4882a593Smuzhiyun void kbase_pm_vsync_callback(int buffer_updated, void *data); 204*4882a593Smuzhiyun 205*4882a593Smuzhiyun /** 206*4882a593Smuzhiyun * kbase_pm_driver_suspend() - Put GPU and driver in suspend state 207*4882a593Smuzhiyun * @kbdev: The kbase device structure for the device (must be a valid pointer) 208*4882a593Smuzhiyun * 209*4882a593Smuzhiyun * Suspend the GPU and prevent any further register accesses to it from Kernel 210*4882a593Smuzhiyun * threads. 211*4882a593Smuzhiyun * 212*4882a593Smuzhiyun * This is called in response to an OS suspend event, and calls into the various 213*4882a593Smuzhiyun * kbase components to complete the suspend. 214*4882a593Smuzhiyun * 215*4882a593Smuzhiyun * Despite kbase_pm_suspend(), it will ignore to update Arbiter 216*4882a593Smuzhiyun * status if MALI_ARBITER_SUPPORT is enabled. 217*4882a593Smuzhiyun * 218*4882a593Smuzhiyun * @note the mechanisms used here rely on all user-space threads being frozen 219*4882a593Smuzhiyun * by the OS before we suspend. Otherwise, an IOCTL could occur that powers up 220*4882a593Smuzhiyun * the GPU e.g. via atom submission. 221*4882a593Smuzhiyun * 222*4882a593Smuzhiyun * Return: 0 on success. 223*4882a593Smuzhiyun */ 224*4882a593Smuzhiyun int kbase_pm_driver_suspend(struct kbase_device *kbdev); 225*4882a593Smuzhiyun 226*4882a593Smuzhiyun /** 227*4882a593Smuzhiyun * kbase_pm_driver_resume() - Put GPU and driver in resume 228*4882a593Smuzhiyun * @kbdev: The kbase device structure for the device (must be a valid pointer) 229*4882a593Smuzhiyun * @arb_gpu_start: Arbiter has notified we can use GPU 230*4882a593Smuzhiyun * 231*4882a593Smuzhiyun * Resume the GPU, allow register accesses to it, and resume running atoms on 232*4882a593Smuzhiyun * the GPU. 233*4882a593Smuzhiyun * 234*4882a593Smuzhiyun * This is called in response to an OS resume event, and calls into the various 235*4882a593Smuzhiyun * kbase components to complete the resume. 236*4882a593Smuzhiyun * 237*4882a593Smuzhiyun * Also called when using VM arbiter, when GPU access has been granted. 238*4882a593Smuzhiyun * 239*4882a593Smuzhiyun * Despite kbase_pm_resume(), it will ignore to update Arbiter 240*4882a593Smuzhiyun * status if MALI_ARBITER_SUPPORT is enabled. 241*4882a593Smuzhiyun */ 242*4882a593Smuzhiyun void kbase_pm_driver_resume(struct kbase_device *kbdev, bool arb_gpu_start); 243*4882a593Smuzhiyun 244*4882a593Smuzhiyun #ifdef CONFIG_MALI_ARBITER_SUPPORT 245*4882a593Smuzhiyun /** 246*4882a593Smuzhiyun * kbase_pm_handle_gpu_lost() - Handle GPU Lost for the VM 247*4882a593Smuzhiyun * @kbdev: Device pointer 248*4882a593Smuzhiyun * 249*4882a593Smuzhiyun * Handles the case that the Arbiter has forced the GPU away from the VM, 250*4882a593Smuzhiyun * so that interrupts will not be received and registers are no longer 251*4882a593Smuzhiyun * accessible because replaced by dummy RAM. 252*4882a593Smuzhiyun * Kill any running tasks and put the driver into a GPU powered-off state. 253*4882a593Smuzhiyun */ 254*4882a593Smuzhiyun void kbase_pm_handle_gpu_lost(struct kbase_device *kbdev); 255*4882a593Smuzhiyun #endif /* CONFIG_MALI_ARBITER_SUPPORT */ 256*4882a593Smuzhiyun 257*4882a593Smuzhiyun #endif /* _KBASE_PM_H_ */ 258