summaryrefslogtreecommitdiff
path: root/drivers/gpu/arm/midgard/mali_kbase_instr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/arm/midgard/mali_kbase_instr.c')
-rw-r--r--drivers/gpu/arm/midgard/mali_kbase_instr.c129
1 files changed, 129 insertions, 0 deletions
diff --git a/drivers/gpu/arm/midgard/mali_kbase_instr.c b/drivers/gpu/arm/midgard/mali_kbase_instr.c
new file mode 100644
index 000000000000..fda317b90176
--- /dev/null
+++ b/drivers/gpu/arm/midgard/mali_kbase_instr.c
@@ -0,0 +1,129 @@
+/*
+ *
+ * (C) COPYRIGHT 2011-2015 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained
+ * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+
+
+/*
+ * Base kernel instrumentation APIs.
+ */
+
+#include <mali_kbase.h>
+#include <mali_midg_regmap.h>
+
+void kbase_instr_hwcnt_suspend(struct kbase_device *kbdev)
+{
+ struct kbase_context *kctx;
+
+ KBASE_DEBUG_ASSERT(kbdev);
+ KBASE_DEBUG_ASSERT(!kbdev->hwcnt.suspended_kctx);
+
+ kctx = kbdev->hwcnt.kctx;
+ kbdev->hwcnt.suspended_kctx = kctx;
+
+ /* Relevant state was saved into hwcnt.suspended_state when enabling the
+ * counters */
+
+ if (kctx) {
+ KBASE_DEBUG_ASSERT(kctx->jctx.sched_info.ctx.flags &
+ KBASE_CTX_FLAG_PRIVILEGED);
+ kbase_instr_hwcnt_disable(kctx);
+ }
+}
+
+void kbase_instr_hwcnt_resume(struct kbase_device *kbdev)
+{
+ struct kbase_context *kctx;
+
+ KBASE_DEBUG_ASSERT(kbdev);
+
+ kctx = kbdev->hwcnt.suspended_kctx;
+ kbdev->hwcnt.suspended_kctx = NULL;
+
+ if (kctx) {
+ int err;
+
+ err = kbase_instr_hwcnt_enable_internal(kbdev, kctx,
+ &kbdev->hwcnt.suspended_state);
+ WARN(err, "Failed to restore instrumented hardware counters on resume\n");
+ }
+}
+
+int kbase_instr_hwcnt_enable(struct kbase_context *kctx,
+ struct kbase_uk_hwcnt_setup *setup)
+{
+ struct kbase_device *kbdev;
+ int err;
+
+ kbdev = kctx->kbdev;
+
+ /* Mark the context as active so the GPU is kept turned on */
+ /* A suspend won't happen here, because we're in a syscall from a
+ * userspace thread. */
+ kbase_pm_context_active(kbdev);
+
+ /* Schedule the context in */
+ kbasep_js_schedule_privileged_ctx(kbdev, kctx);
+ err = kbase_instr_hwcnt_enable_internal(kbdev, kctx, setup);
+ if (err) {
+ /* Release the context. This had its own Power Manager Active
+ * reference */
+ kbasep_js_release_privileged_ctx(kbdev, kctx);
+
+ /* Also release our Power Manager Active reference */
+ kbase_pm_context_idle(kbdev);
+ }
+
+ return err;
+}
+KBASE_EXPORT_SYMBOL(kbase_instr_hwcnt_enable);
+
+int kbase_instr_hwcnt_disable(struct kbase_context *kctx)
+{
+ int err = -EINVAL;
+ struct kbase_device *kbdev = kctx->kbdev;
+
+ err = kbase_instr_hwcnt_disable_internal(kctx);
+ if (err)
+ goto out;
+
+ /* Release the context. This had its own Power Manager Active reference
+ */
+ kbasep_js_release_privileged_ctx(kbdev, kctx);
+
+ /* Also release our Power Manager Active reference */
+ kbase_pm_context_idle(kbdev);
+
+ dev_dbg(kbdev->dev, "HW counters dumping disabled for context %p",
+ kctx);
+out:
+ return err;
+}
+KBASE_EXPORT_SYMBOL(kbase_instr_hwcnt_disable);
+
+int kbase_instr_hwcnt_dump(struct kbase_context *kctx)
+{
+ int err;
+
+ err = kbase_instr_hwcnt_request_dump(kctx);
+ if (err)
+ return err;
+
+ err = kbase_instr_hwcnt_wait_for_dump(kctx);
+ return err;
+}
+KBASE_EXPORT_SYMBOL(kbase_instr_hwcnt_dump);
+