| .. | .. |
|---|
| 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) |
|---|