From 72f2457ff7355ff0389efe5bc9cec3365362d8c4 Mon Sep 17 00:00:00 2001 From: Sidath Senanayake Date: Tue, 27 Oct 2020 11:38:49 +0000 Subject: 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 Change-Id: Ib59de731b034cc7e2631e35f1b0063b8f6894ecc --- mali_kbase/backend/gpu/mali_kbase_pm_backend.c | 147 ++++++++++++++++--------- 1 file changed, 94 insertions(+), 53 deletions(-) (limited to 'mali_kbase/backend/gpu/mali_kbase_pm_backend.c') 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 #include +#if !MALI_USE_CSF #include #include #include +#endif /* !MALI_USE_CSF */ #include #include #include @@ -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 */ -- cgit v1.2.3