hc
2024-05-16 8d2a02b24d66aa359e83eebc1ed3c0f85367a1cb
kernel/drivers/gpu/arm/bifrost/backend/gpu/mali_kbase_pm_policy.c
....@@ -1,7 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
22 /*
33 *
4
- * (C) COPYRIGHT 2010-2021 ARM Limited. All rights reserved.
4
+ * (C) COPYRIGHT 2010-2022 ARM Limited. All rights reserved.
55 *
66 * This program is free software and is provided to you under the terms of the
77 * GNU General Public License version 2 as published by the Free Software
....@@ -36,8 +36,13 @@
3636 #include <linux/of.h>
3737
3838 static const struct kbase_pm_policy *const all_policy_list[] = {
39
+#if IS_ENABLED(CONFIG_MALI_BIFROST_NO_MALI)
40
+ &kbase_pm_always_on_policy_ops,
3941 &kbase_pm_coarse_demand_policy_ops,
40
- &kbase_pm_always_on_policy_ops
42
+#else /* CONFIG_MALI_BIFROST_NO_MALI */
43
+ &kbase_pm_coarse_demand_policy_ops,
44
+ &kbase_pm_always_on_policy_ops,
45
+#endif /* CONFIG_MALI_BIFROST_NO_MALI */
4146 };
4247
4348 void kbase_pm_policy_init(struct kbase_device *kbdev)
....@@ -175,15 +180,14 @@
175180
176181 shaders_desired = kbdev->pm.backend.pm_current_policy->shaders_needed(kbdev);
177182
178
- if (shaders_desired && kbase_pm_is_l2_desired(kbdev)) {
183
+ if (shaders_desired && kbase_pm_is_l2_desired(kbdev))
179184 kbase_pm_update_state(kbdev);
180
- }
181185 #endif
182186 }
183187
184188 void kbase_pm_update_cores_state_nolock(struct kbase_device *kbdev)
185189 {
186
- bool shaders_desired;
190
+ bool shaders_desired = false;
187191
188192 lockdep_assert_held(&kbdev->hwaccess_lock);
189193
....@@ -192,6 +196,7 @@
192196 if (kbdev->pm.backend.poweroff_wait_in_progress)
193197 return;
194198
199
+#if !MALI_USE_CSF
195200 if (kbdev->pm.backend.protected_transition_override)
196201 /* We are trying to change in/out of protected mode - force all
197202 * cores off so that the L2 powers down
....@@ -199,15 +204,8 @@
199204 shaders_desired = false;
200205 else
201206 shaders_desired = kbdev->pm.backend.pm_current_policy->shaders_needed(kbdev);
202
-
203
-#if MALI_USE_CSF
204
- /* On CSF GPUs, Host driver isn't supposed to do the power management
205
- * for shader cores. CSF firmware will power up the cores appropriately
206
- * and so from Driver's standpoint 'shaders_desired' flag shall always
207
- * remain 0.
208
- */
209
- shaders_desired = false;
210207 #endif
208
+
211209 if (kbdev->pm.backend.shaders_desired != shaders_desired) {
212210 KBASE_KTRACE_ADD(kbdev, PM_CORES_CHANGE_DESIRED, NULL, kbdev->pm.backend.shaders_desired);
213211
....@@ -250,9 +248,8 @@
250248 #if MALI_USE_CSF
251249 static int policy_change_wait_for_L2_off(struct kbase_device *kbdev)
252250 {
253
-#define WAIT_DURATION_MS (3000)
254251 long remaining;
255
- long timeout = kbase_csf_timeout_in_jiffies(WAIT_DURATION_MS);
252
+ long timeout = kbase_csf_timeout_in_jiffies(kbase_get_timeout_ms(kbdev, CSF_PM_TIMEOUT));
256253 int err = 0;
257254
258255 /* Wait for L2 becoming off, by which the MCU is also implicitly off
....@@ -295,6 +292,8 @@
295292 unsigned int new_policy_csf_pm_sched_flags;
296293 bool sched_suspend;
297294 bool reset_gpu = false;
295
+ bool reset_op_prevented = true;
296
+ struct kbase_csf_scheduler *scheduler = NULL;
298297 #endif
299298
300299 KBASE_DEBUG_ASSERT(kbdev != NULL);
....@@ -303,9 +302,23 @@
303302 KBASE_KTRACE_ADD(kbdev, PM_SET_POLICY, NULL, new_policy->id);
304303
305304 #if MALI_USE_CSF
305
+ scheduler = &kbdev->csf.scheduler;
306
+ KBASE_DEBUG_ASSERT(scheduler != NULL);
307
+
306308 /* Serialize calls on kbase_pm_set_policy() */
307309 mutex_lock(&kbdev->pm.backend.policy_change_lock);
308310
311
+ if (kbase_reset_gpu_prevent_and_wait(kbdev)) {
312
+ dev_warn(kbdev->dev, "Set PM policy failing to prevent gpu reset");
313
+ reset_op_prevented = false;
314
+ }
315
+
316
+ /* In case of CSF, the scheduler may be invoked to suspend. In that
317
+ * case, there is a risk that the L2 may be turned on by the time we
318
+ * check it here. So we hold the scheduler lock to avoid other operations
319
+ * interfering with the policy change and vice versa.
320
+ */
321
+ mutex_lock(&scheduler->lock);
309322 spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
310323 /* policy_change_clamp_state_to_off, when needed, is set/cleared in
311324 * this function, a very limited temporal scope for covering the
....@@ -318,24 +331,22 @@
318331 * the always_on policy, reflected by the CSF_DYNAMIC_PM_CORE_KEEP_ON
319332 * flag bit.
320333 */
321
- sched_suspend = kbdev->csf.firmware_inited &&
334
+ sched_suspend = reset_op_prevented &&
322335 (CSF_DYNAMIC_PM_CORE_KEEP_ON &
323
- (new_policy_csf_pm_sched_flags |
324
- kbdev->pm.backend.csf_pm_sched_flags));
336
+ (new_policy_csf_pm_sched_flags | kbdev->pm.backend.csf_pm_sched_flags));
325337
326338 spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
327339
328
- if (sched_suspend)
329
- kbase_csf_scheduler_pm_suspend(kbdev);
340
+ if (sched_suspend) {
341
+ /* Update the suspend flag to reflect actually suspend being done ! */
342
+ sched_suspend = !kbase_csf_scheduler_pm_suspend_no_lock(kbdev);
343
+ /* Set the reset recovery flag if the required suspend failed */
344
+ reset_gpu = !sched_suspend;
345
+ }
330346
331347 spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
332
- /* If the current active policy is always_on, one needs to clamp the
333
- * MCU/L2 for reaching off-state
334
- */
335
- if (sched_suspend)
336
- kbdev->pm.backend.policy_change_clamp_state_to_off =
337
- CSF_DYNAMIC_PM_CORE_KEEP_ON & kbdev->pm.backend.csf_pm_sched_flags;
338348
349
+ kbdev->pm.backend.policy_change_clamp_state_to_off = sched_suspend;
339350 kbase_pm_update_state(kbdev);
340351 spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
341352
....@@ -394,13 +405,19 @@
394405
395406 #if MALI_USE_CSF
396407 /* Reverse the suspension done */
408
+ if (sched_suspend)
409
+ kbase_csf_scheduler_pm_resume_no_lock(kbdev);
410
+ mutex_unlock(&scheduler->lock);
411
+
412
+ if (reset_op_prevented)
413
+ kbase_reset_gpu_allow(kbdev);
414
+
397415 if (reset_gpu) {
398416 dev_warn(kbdev->dev, "Resorting to GPU reset for policy change\n");
399417 if (kbase_prepare_to_reset_gpu(kbdev, RESET_FLAGS_NONE))
400418 kbase_reset_gpu(kbdev);
401419 kbase_reset_gpu_wait(kbdev);
402
- } else if (sched_suspend)
403
- kbase_csf_scheduler_pm_resume(kbdev);
420
+ }
404421
405422 mutex_unlock(&kbdev->pm.backend.policy_change_lock);
406423 #endif