summaryrefslogtreecommitdiff
path: root/mali_kbase/backend/gpu/mali_kbase_pm_backend.c
diff options
context:
space:
mode:
authorSidath Senanayake <sidaths@google.com>2020-10-27 11:38:49 +0000
committerSidath Senanayake <sidaths@google.com>2020-10-27 11:38:49 +0000
commit72f2457ff7355ff0389efe5bc9cec3365362d8c4 (patch)
tree8f5fb993bd2a8eb181c880b180b6401b46f76620 /mali_kbase/backend/gpu/mali_kbase_pm_backend.c
parentd4ca6eb7268ee2db9deabd1745b505c6e1c162f9 (diff)
downloadgpu-72f2457ff7355ff0389efe5bc9cec3365362d8c4.tar.gz
Mali Valhall DDK r27p0 KMD
Provenance: 7e6f74ec1 (collaborate/EAC/v_r27p0) VX504X08X-BU-00000-r27p0-01eac0 - Android DDK VX504X08X-SW-99006-r27p0-01eac0 - Android Renderscript AOSP parts VX504X08X-BU-60000-r27p0-01eac0 - Android Document Bundle VX504X08X-DC-11001-r27p0-01eac0 - Valhall Android DDK Software Errata Signed-off-by: Sidath Senanayake <sidaths@google.com> Change-Id: Ib59de731b034cc7e2631e35f1b0063b8f6894ecc
Diffstat (limited to 'mali_kbase/backend/gpu/mali_kbase_pm_backend.c')
-rw-r--r--mali_kbase/backend/gpu/mali_kbase_pm_backend.c147
1 files changed, 94 insertions, 53 deletions
diff --git a/mali_kbase/backend/gpu/mali_kbase_pm_backend.c b/mali_kbase/backend/gpu/mali_kbase_pm_backend.c
index 576c9f2..c43bf64 100644
--- a/mali_kbase/backend/gpu/mali_kbase_pm_backend.c
+++ b/mali_kbase/backend/gpu/mali_kbase_pm_backend.c
@@ -30,9 +30,11 @@
#include <mali_kbase_config_defaults.h>
#include <mali_kbase_pm.h>
+#if !MALI_USE_CSF
#include <mali_kbase_hwaccess_jm.h>
#include <backend/gpu/mali_kbase_js_internal.h>
#include <backend/gpu/mali_kbase_jm_internal.h>
+#endif /* !MALI_USE_CSF */
#include <mali_kbase_hwcnt_context.h>
#include <backend/gpu/mali_kbase_pm_internal.h>
#include <backend/gpu/mali_kbase_devfreq.h>
@@ -106,6 +108,11 @@ void kbase_pm_register_access_enable(struct kbase_device *kbdev)
if (callbacks)
callbacks->power_on_callback(kbdev);
+#ifdef CONFIG_MALI_ARBITER_SUPPORT
+ if (WARN_ON(kbase_pm_is_gpu_lost(kbdev)))
+ dev_err(kbdev->dev, "Attempting to power on while GPU lost\n");
+#endif
+
kbdev->pm.backend.gpu_powered = true;
}
@@ -139,9 +146,10 @@ int kbase_hwaccess_pm_init(struct kbase_device *kbdev)
kbdev->pm.backend.ca_cores_enabled = ~0ull;
kbdev->pm.backend.gpu_powered = false;
+ kbdev->pm.backend.gpu_ready = false;
kbdev->pm.suspending = false;
#ifdef CONFIG_MALI_ARBITER_SUPPORT
- kbdev->pm.gpu_lost = false;
+ kbase_pm_set_gpu_lost(kbdev, false);
#endif
#ifdef CONFIG_MALI_DEBUG
kbdev->pm.backend.driver_ready_for_irqs = false;
@@ -251,13 +259,20 @@ static void kbase_pm_gpu_poweroff_wait_wq(struct work_struct *data)
struct kbase_pm_backend_data *backend = &pm->backend;
unsigned long flags;
+#if !MALI_USE_CSF
/* Wait for power transitions to complete. We do this with no locks held
* so that we don't deadlock with any pending workqueues.
*/
kbase_pm_wait_for_desired_state(kbdev);
+#endif
kbase_pm_lock(kbdev);
+#ifdef CONFIG_MALI_ARBITER_SUPPORT
+ if (kbase_pm_is_gpu_lost(kbdev))
+ backend->poweron_required = false;
+#endif
+
if (!backend->poweron_required) {
unsigned long flags;
@@ -278,6 +293,14 @@ static void kbase_pm_gpu_poweroff_wait_wq(struct work_struct *data)
kbase_flush_mmu_wqs(kbdev);
kbase_pm_lock(kbdev);
+#ifdef CONFIG_MALI_ARBITER_SUPPORT
+ /* poweron_required may have changed while pm lock
+ * was released.
+ */
+ if (kbase_pm_is_gpu_lost(kbdev))
+ backend->poweron_required = false;
+#endif
+
/* Turn off clock now that fault have been handled. We
* dropped locks so poweron_required may have changed -
* power back on if this is the case (effectively only
@@ -296,9 +319,14 @@ static void kbase_pm_gpu_poweroff_wait_wq(struct work_struct *data)
if (backend->poweron_required) {
backend->poweron_required = false;
kbdev->pm.backend.l2_desired = true;
+#if MALI_USE_CSF
+ kbdev->pm.backend.mcu_desired = true;
+#endif
kbase_pm_update_state(kbdev);
kbase_pm_update_cores_state_nolock(kbdev);
+#if !MALI_USE_CSF
kbase_backend_slot_update(kbdev);
+#endif /* !MALI_USE_CSF */
}
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
@@ -451,7 +479,9 @@ static void kbase_pm_hwcnt_disable_worker(struct work_struct *data)
*/
backend->hwcnt_disabled = true;
kbase_pm_update_state(kbdev);
+#if !MALI_USE_CSF
kbase_backend_slot_update(kbdev);
+#endif /* !MALI_USE_CSF */
} else {
/* PM state was updated while we were doing the disable,
* so we need to undo the disable we just performed.
@@ -476,8 +506,12 @@ void kbase_pm_do_poweroff(struct kbase_device *kbdev)
if (kbdev->pm.backend.poweroff_wait_in_progress)
goto unlock_hwaccess;
+#if MALI_USE_CSF
+ kbdev->pm.backend.mcu_desired = false;
+#else
/* Force all cores off */
kbdev->pm.backend.shaders_desired = false;
+#endif
kbdev->pm.backend.l2_desired = false;
kbdev->pm.backend.poweroff_wait_in_progress = true;
@@ -559,7 +593,20 @@ int kbase_hwaccess_pm_powerup(struct kbase_device *kbdev,
#endif
kbase_pm_enable_interrupts(kbdev);
+ WARN_ON(!kbdev->pm.backend.gpu_powered);
+ /* GPU has been powered up (by kbase_pm_init_hw) and interrupts have
+ * been enabled, so GPU is ready for use and PM state machine can be
+ * exercised from this point onwards.
+ */
+ kbdev->pm.backend.gpu_ready = true;
+
/* Turn on the GPU and any cores needed by the policy */
+#if MALI_USE_CSF
+ /* Turn on the L2 caches, needed for firmware boot */
+ spin_lock_irqsave(&kbdev->hwaccess_lock, irq_flags);
+ kbdev->pm.backend.l2_desired = true;
+ spin_unlock_irqrestore(&kbdev->hwaccess_lock, irq_flags);
+#endif
kbase_pm_do_poweron(kbdev, false);
kbase_pm_unlock(kbdev);
@@ -611,7 +658,9 @@ void kbase_pm_power_changed(struct kbase_device *kbdev)
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
kbase_pm_update_state(kbdev);
+#if !MALI_USE_CSF
kbase_backend_slot_update(kbdev);
+#endif /* !MALI_USE_CSF */
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
}
@@ -656,7 +705,9 @@ void kbase_hwaccess_pm_suspend(struct kbase_device *kbdev)
kbase_pm_do_poweroff(kbdev);
+#if !MALI_USE_CSF
kbase_backend_timer_suspend(kbdev);
+#endif /* !MALI_USE_CSF */
kbase_pm_unlock(kbdev);
@@ -672,11 +723,17 @@ void kbase_hwaccess_pm_resume(struct kbase_device *kbdev)
kbdev->pm.suspending = false;
#ifdef CONFIG_MALI_ARBITER_SUPPORT
- kbdev->pm.gpu_lost = false;
+ if (kbase_pm_is_gpu_lost(kbdev)) {
+ dev_dbg(kbdev->dev, "%s: GPU lost in progress\n", __func__);
+ kbase_pm_unlock(kbdev);
+ return;
+ }
#endif
kbase_pm_do_poweron(kbdev, true);
+#if !MALI_USE_CSF
kbase_backend_timer_resume(kbdev);
+#endif /* !MALI_USE_CSF */
kbase_pm_unlock(kbdev);
}
@@ -685,63 +742,47 @@ void kbase_hwaccess_pm_resume(struct kbase_device *kbdev)
void kbase_pm_handle_gpu_lost(struct kbase_device *kbdev)
{
unsigned long flags;
- struct kbase_pm_backend_data *backend = &kbdev->pm.backend;
ktime_t end_timestamp = ktime_get();
+ struct kbase_arbiter_vm_state *arb_vm_state = kbdev->pm.arb_vm_state;
- /* Full GPU reset will have been done by hypervisor, so cancel */
- atomic_set(&kbdev->hwaccess.backend.reset_gpu,
- KBASE_RESET_GPU_NOT_PENDING);
- hrtimer_cancel(&kbdev->hwaccess.backend.reset_timer);
-
- /* GPU is no longer mapped to VM. So no interrupts will be received
- * and Mali registers have been replaced by dummy RAM
- */
- spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
- spin_lock(&kbdev->mmu_mask_change);
- kbdev->irq_reset_flush = true;
- spin_unlock(&kbdev->mmu_mask_change);
- spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
- kbase_synchronize_irqs(kbdev);
- kbase_flush_mmu_wqs(kbdev);
- kbdev->irq_reset_flush = false;
-
- /* Clear all jobs running on the GPU */
mutex_lock(&kbdev->pm.lock);
- kbdev->pm.gpu_lost = true;
- spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
- kbdev->protected_mode = false;
- if (!kbdev->pm.backend.protected_entry_transition_override)
- kbase_backend_reset(kbdev, &end_timestamp);
- kbase_pm_metrics_update(kbdev, NULL);
- spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
+ mutex_lock(&arb_vm_state->vm_state_lock);
+ if (kbdev->pm.backend.gpu_powered &&
+ !kbase_pm_is_gpu_lost(kbdev)) {
+ kbase_pm_set_gpu_lost(kbdev, true);
+
+ /* GPU is no longer mapped to VM. So no interrupts will
+ * be received and Mali registers have been replaced by
+ * dummy RAM
+ */
+ WARN(!kbase_is_gpu_removed(kbdev),
+ "GPU is still available after GPU lost event\n");
- /* Cancel any pending HWC dumps */
- spin_lock_irqsave(&kbdev->hwcnt.lock, flags);
- kbdev->hwcnt.backend.state = KBASE_INSTR_STATE_IDLE;
- kbdev->hwcnt.backend.triggered = 1;
- wake_up(&kbdev->hwcnt.backend.wait);
- spin_unlock_irqrestore(&kbdev->hwcnt.lock, flags);
+ /* Full GPU reset will have been done by hypervisor, so
+ * cancel
+ */
+ atomic_set(&kbdev->hwaccess.backend.reset_gpu,
+ KBASE_RESET_GPU_NOT_PENDING);
+ hrtimer_cancel(&kbdev->hwaccess.backend.reset_timer);
+ kbase_synchronize_irqs(kbdev);
- /* Wait for all threads keeping GPU active to complete */
- mutex_unlock(&kbdev->pm.lock);
- wait_event(kbdev->pm.zero_active_count_wait,
- kbdev->pm.active_count == 0);
- mutex_lock(&kbdev->pm.lock);
+ /* Clear all jobs running on the GPU */
+ spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
+ kbdev->protected_mode = false;
+ kbase_backend_reset(kbdev, &end_timestamp);
+ kbase_pm_metrics_update(kbdev, NULL);
+ kbase_pm_update_state(kbdev);
+ spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
- /* Update state to GPU off */
- spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
- kbdev->pm.backend.shaders_desired = false;
- kbdev->pm.backend.l2_desired = false;
- backend->l2_state = KBASE_L2_OFF;
- backend->shaders_state = KBASE_SHADERS_OFF_CORESTACK_OFF;
- kbdev->pm.backend.gpu_powered = false;
- backend->poweroff_wait_in_progress = false;
- KBASE_KTRACE_ADD(kbdev, PM_WAKE_WAITERS, NULL, 0);
- wake_up(&kbdev->pm.backend.gpu_in_desired_state_wait);
- kbase_gpu_cache_clean_wait_complete(kbdev);
- backend->poweroff_wait_in_progress = false;
- spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
- wake_up(&kbdev->pm.backend.poweroff_wait);
+ /* Cancel any pending HWC dumps */
+ spin_lock_irqsave(&kbdev->hwcnt.lock, flags);
+ kbdev->hwcnt.backend.state = KBASE_INSTR_STATE_IDLE;
+ kbdev->hwcnt.backend.triggered = 1;
+ wake_up(&kbdev->hwcnt.backend.wait);
+ spin_unlock_irqrestore(&kbdev->hwcnt.lock, flags);
+ }
+ mutex_unlock(&arb_vm_state->vm_state_lock);
mutex_unlock(&kbdev->pm.lock);
}
+
#endif /* CONFIG_MALI_ARBITER_SUPPORT */