.. | .. |
---|
1 | 1 | // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note |
---|
2 | 2 | /* |
---|
3 | 3 | * |
---|
4 | | - * (C) COPYRIGHT 2010-2021 ARM Limited. All rights reserved. |
---|
| 4 | + * (C) COPYRIGHT 2010-2022 ARM Limited. All rights reserved. |
---|
5 | 5 | * |
---|
6 | 6 | * This program is free software and is provided to you under the terms of the |
---|
7 | 7 | * GNU General Public License version 2 as published by the Free Software |
---|
.. | .. |
---|
26 | 26 | #include <mali_kbase.h> |
---|
27 | 27 | #include <gpu/mali_kbase_gpu_regmap.h> |
---|
28 | 28 | #include <mali_kbase_vinstr.h> |
---|
29 | | -#include <mali_kbase_hwcnt_context.h> |
---|
| 29 | +#include <mali_kbase_kinstr_prfcnt.h> |
---|
| 30 | +#include <hwcnt/mali_kbase_hwcnt_context.h> |
---|
30 | 31 | |
---|
31 | 32 | #include <mali_kbase_pm.h> |
---|
32 | 33 | #include <backend/gpu/mali_kbase_pm_internal.h> |
---|
.. | .. |
---|
76 | 77 | case KBASE_PM_SUSPEND_HANDLER_DONT_REACTIVATE: |
---|
77 | 78 | if (kbdev->pm.active_count != 0) |
---|
78 | 79 | break; |
---|
79 | | - /* FALLTHROUGH */ |
---|
| 80 | + fallthrough; |
---|
80 | 81 | case KBASE_PM_SUSPEND_HANDLER_DONT_INCREASE: |
---|
81 | 82 | kbase_pm_unlock(kbdev); |
---|
82 | 83 | return 1; |
---|
83 | 84 | |
---|
84 | 85 | case KBASE_PM_SUSPEND_HANDLER_NOT_POSSIBLE: |
---|
85 | | - /* FALLTHROUGH */ |
---|
| 86 | + fallthrough; |
---|
86 | 87 | default: |
---|
87 | 88 | KBASE_DEBUG_ASSERT_MSG(false, "unreachable"); |
---|
88 | 89 | break; |
---|
.. | .. |
---|
143 | 144 | |
---|
144 | 145 | KBASE_EXPORT_TEST_API(kbase_pm_context_idle); |
---|
145 | 146 | |
---|
146 | | -void kbase_pm_driver_suspend(struct kbase_device *kbdev) |
---|
| 147 | +int kbase_pm_driver_suspend(struct kbase_device *kbdev) |
---|
147 | 148 | { |
---|
148 | 149 | KBASE_DEBUG_ASSERT(kbdev); |
---|
149 | 150 | |
---|
150 | | - /* Suspend vinstr. This blocks until the vinstr worker and timer are |
---|
151 | | - * no longer running. |
---|
| 151 | + /* Suspend HW counter intermediaries. This blocks until workers and timers |
---|
| 152 | + * are no longer running. |
---|
152 | 153 | */ |
---|
153 | 154 | kbase_vinstr_suspend(kbdev->vinstr_ctx); |
---|
| 155 | + kbase_kinstr_prfcnt_suspend(kbdev->kinstr_prfcnt_ctx); |
---|
154 | 156 | |
---|
155 | 157 | /* Disable GPU hardware counters. |
---|
156 | 158 | * This call will block until counters are disabled. |
---|
.. | .. |
---|
160 | 162 | mutex_lock(&kbdev->pm.lock); |
---|
161 | 163 | if (WARN_ON(kbase_pm_is_suspending(kbdev))) { |
---|
162 | 164 | mutex_unlock(&kbdev->pm.lock); |
---|
163 | | - return; |
---|
| 165 | + return 0; |
---|
164 | 166 | } |
---|
165 | 167 | kbdev->pm.suspending = true; |
---|
166 | 168 | mutex_unlock(&kbdev->pm.lock); |
---|
.. | .. |
---|
191 | 193 | */ |
---|
192 | 194 | kbasep_js_suspend(kbdev); |
---|
193 | 195 | #else |
---|
194 | | - kbase_csf_scheduler_pm_suspend(kbdev); |
---|
| 196 | + if (kbase_csf_scheduler_pm_suspend(kbdev)) { |
---|
| 197 | + mutex_lock(&kbdev->pm.lock); |
---|
| 198 | + kbdev->pm.suspending = false; |
---|
| 199 | + mutex_unlock(&kbdev->pm.lock); |
---|
| 200 | + return -1; |
---|
| 201 | + } |
---|
195 | 202 | #endif |
---|
196 | 203 | |
---|
197 | 204 | /* Wait for the active count to reach zero. This is not the same as |
---|
.. | .. |
---|
207 | 214 | /* NOTE: We synchronize with anything that was just finishing a |
---|
208 | 215 | * kbase_pm_context_idle() call by locking the pm.lock below |
---|
209 | 216 | */ |
---|
210 | | - kbase_hwaccess_pm_suspend(kbdev); |
---|
| 217 | + if (kbase_hwaccess_pm_suspend(kbdev)) { |
---|
| 218 | + mutex_lock(&kbdev->pm.lock); |
---|
| 219 | + kbdev->pm.suspending = false; |
---|
| 220 | + mutex_unlock(&kbdev->pm.lock); |
---|
| 221 | + return -1; |
---|
| 222 | + } |
---|
211 | 223 | |
---|
212 | 224 | #ifdef CONFIG_MALI_ARBITER_SUPPORT |
---|
213 | 225 | if (kbdev->arb.arb_if) { |
---|
.. | .. |
---|
216 | 228 | mutex_unlock(&kbdev->pm.arb_vm_state->vm_state_lock); |
---|
217 | 229 | } |
---|
218 | 230 | #endif /* CONFIG_MALI_ARBITER_SUPPORT */ |
---|
| 231 | + |
---|
| 232 | + return 0; |
---|
219 | 233 | } |
---|
220 | 234 | |
---|
221 | 235 | void kbase_pm_driver_resume(struct kbase_device *kbdev, bool arb_gpu_start) |
---|
.. | .. |
---|
246 | 260 | * atoms |
---|
247 | 261 | */ |
---|
248 | 262 | kbasep_js_resume(kbdev); |
---|
249 | | -#else |
---|
250 | | - kbase_csf_scheduler_pm_resume(kbdev); |
---|
251 | 263 | #endif |
---|
252 | 264 | |
---|
253 | 265 | /* Matching idle call, to power off the GPU/cores if we didn't actually |
---|
.. | .. |
---|
266 | 278 | spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags); |
---|
267 | 279 | #endif |
---|
268 | 280 | |
---|
269 | | - /* Resume vinstr */ |
---|
| 281 | + /* Resume HW counters intermediaries. */ |
---|
270 | 282 | kbase_vinstr_resume(kbdev->vinstr_ctx); |
---|
| 283 | + kbase_kinstr_prfcnt_resume(kbdev->kinstr_prfcnt_ctx); |
---|
271 | 284 | } |
---|
272 | 285 | |
---|
273 | | -void kbase_pm_suspend(struct kbase_device *kbdev) |
---|
| 286 | +int kbase_pm_suspend(struct kbase_device *kbdev) |
---|
274 | 287 | { |
---|
| 288 | + int result = 0; |
---|
275 | 289 | #ifdef CONFIG_MALI_ARBITER_SUPPORT |
---|
276 | 290 | if (kbdev->arb.arb_if) |
---|
277 | 291 | kbase_arbiter_pm_vm_event(kbdev, KBASE_VM_OS_SUSPEND_EVENT); |
---|
278 | 292 | else |
---|
279 | | - kbase_pm_driver_suspend(kbdev); |
---|
| 293 | + result = kbase_pm_driver_suspend(kbdev); |
---|
280 | 294 | #else |
---|
281 | | - kbase_pm_driver_suspend(kbdev); |
---|
| 295 | + result = kbase_pm_driver_suspend(kbdev); |
---|
282 | 296 | #endif /* CONFIG_MALI_ARBITER_SUPPORT */ |
---|
| 297 | + |
---|
| 298 | + return result; |
---|
283 | 299 | } |
---|
284 | 300 | |
---|
285 | 301 | void kbase_pm_resume(struct kbase_device *kbdev) |
---|