summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSuzanne Candanedo <suzanne.candanedo@arm.com>2022-11-30 11:57:07 +0000
committerKevin DuBois <kevindubois@google.com>2022-12-14 18:26:20 +0000
commit54d08583ff687f3148f1a12e4460c9b33ee53643 (patch)
tree515dabee392a2b477613c293eaf9f7f570fde0fe
parentff4bc27090562bd58d0937b48f50d3b1dd933249 (diff)
downloadgpu-54d08583ff687f3148f1a12e4460c9b33ee53643.tar.gz
GPUCORE-32316: Wait for AS_ACTIVE_INT to become 0 before L2 poweroff
Change-Id: I86ecbdba8cdd3b18c0da137cc4194e7cb034101d Provenance: https://code.ipdelivery.arm.com/c/GPU/mali-ddk/+/4761 Bug: 243522189 Bug: 241217496 Test: Tested GPU reset as b/241217496#comment8 (cherry picked from commit b5aada133a2a9d9dc439296c67a24a3f4130a7b8)
-rw-r--r--mali_kbase/backend/gpu/mali_kbase_pm_driver.c53
1 files changed, 51 insertions, 2 deletions
diff --git a/mali_kbase/backend/gpu/mali_kbase_pm_driver.c b/mali_kbase/backend/gpu/mali_kbase_pm_driver.c
index aab07c9..840ca26 100644
--- a/mali_kbase/backend/gpu/mali_kbase_pm_driver.c
+++ b/mali_kbase/backend/gpu/mali_kbase_pm_driver.c
@@ -1142,6 +1142,54 @@ static void kbase_pm_l2_clear_backend_slot_submit_kctx(struct kbase_device *kbde
}
#endif
+/* wait_as_active_int - Wait for AS_ACTIVE_INT bits to become 0 for all AS
+ *
+ * @kbdev: Pointer to the device.
+ *
+ * This function is supposed to be called before the write to L2_PWROFF register
+ * to wait for AS_ACTIVE_INT bit to become 0 for all the GPU address space slots.
+ * AS_ACTIVE_INT bit can become 1 for an AS, only when L2_READY becomes 1, based
+ * on the value in TRANSCFG register and would become 0 once AS has been reconfigured.
+ */
+static void wait_as_active_int(struct kbase_device *kbdev)
+{
+#if MALI_USE_CSF && !IS_ENABLED(CONFIG_MALI_NO_MALI)
+ int as_no;
+
+ lockdep_assert_held(&kbdev->hwaccess_lock);
+
+ if (!kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_GPU2019_3878))
+ return;
+
+ for (as_no = 0; as_no != kbdev->nr_hw_address_spaces; as_no++) {
+ unsigned int max_loops = KBASE_AS_INACTIVE_MAX_LOOPS;
+
+ /* Wait for the AS_ACTIVE_INT bit to become 0 for the AS.
+ * The wait is actually needed only for the enabled AS.
+ */
+ while (--max_loops &&
+ kbase_reg_read(kbdev, MMU_AS_REG(as_no, AS_STATUS)) &
+ AS_STATUS_AS_ACTIVE_INT)
+ ;
+
+#ifdef CONFIG_MALI_DEBUG
+ /* For a disabled AS the loop should run for a single iteration only. */
+ if (!kbdev->as_to_kctx[as_no] && (max_loops != (KBASE_AS_INACTIVE_MAX_LOOPS -1)))
+ dev_warn(kbdev->dev, "AS_ACTIVE_INT bit found to be set for disabled AS %d", as_no);
+#endif
+
+ if (max_loops)
+ continue;
+
+ dev_warn(kbdev->dev, "AS_ACTIVE_INT bit stuck for AS %d", as_no);
+
+ if (kbase_prepare_to_reset_gpu(kbdev, 0))
+ kbase_reset_gpu(kbdev);
+ return;
+ }
+#endif
+}
+
static bool can_power_down_l2(struct kbase_device *kbdev)
{
#if MALI_USE_CSF
@@ -1460,14 +1508,15 @@ static int kbase_pm_l2_update_state(struct kbase_device *kbdev)
if (kbase_pm_is_l2_desired(kbdev))
backend->l2_state = KBASE_L2_PEND_ON;
else if (can_power_down_l2(kbdev)) {
- if (!backend->l2_always_on)
+ if (!backend->l2_always_on) {
+ wait_as_active_int(kbdev);
/* Powering off the L2 will also power off the
* tiler.
*/
kbase_pm_invoke(kbdev, KBASE_PM_CORE_L2,
l2_present,
ACTION_PWROFF);
- else
+ } else
/* If L2 cache is powered then we must flush it
* before we power off the GPU. Normally this
* would have been handled when the L2 was