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