blob: fda317b90176e5ae2505d34060b483cc407ed7e0 [file] [log] [blame]
/*
*
* (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);