/*
 *
 * (C) COPYRIGHT 2018, 2020 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you can access it online at
 * http://www.gnu.org/licenses/gpl-2.0.html.
 *
 * SPDX-License-Identifier: GPL-2.0
 *
 */

/*
 * Implementation of hardware counter context and accumulator APIs.
 */

#include "mali_kbase_hwcnt_context.h"
#include "mali_kbase_hwcnt_accumulator.h"
#include "mali_kbase_hwcnt_backend.h"
#include "mali_kbase_hwcnt_types.h"
#include "mali_malisw.h"
#include "mali_kbase_debug.h"
#include "mali_kbase_linux.h"

#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/slab.h>

/**
 * enum kbase_hwcnt_accum_state - Hardware counter accumulator states.
 * @ACCUM_STATE_ERROR:    Error state, where all accumulator operations fail.
 * @ACCUM_STATE_DISABLED: Disabled state, where dumping is always disabled.
 * @ACCUM_STATE_ENABLED:  Enabled state, where dumping is enabled if there are
 *                        any enabled counters.
 */
enum kbase_hwcnt_accum_state {
	ACCUM_STATE_ERROR,
	ACCUM_STATE_DISABLED,
	ACCUM_STATE_ENABLED
};

/**
 * struct kbase_hwcnt_accumulator - Hardware counter accumulator structure.
 * @backend:                Pointer to created counter backend.
 * @state:                  The current state of the accumulator.
 *                           - State transition from disabled->enabled or
 *                             disabled->error requires state_lock.
 *                           - State transition from enabled->disabled or
 *                             enabled->error requires both accum_lock and
 *                             state_lock.
 *                           - Error state persists until next disable.
 * @enable_map:             The current set of enabled counters.
 *                           - Must only be modified while holding both
 *                             accum_lock and state_lock.
 *                           - Can be read while holding either lock.
 *                           - Must stay in sync with enable_map_any_enabled.
 * @enable_map_any_enabled: True if any counters in the map are enabled, else
 *                          false. If true, and state is ACCUM_STATE_ENABLED,
 *                          then the counter backend will be enabled.
 *                           - Must only be modified while holding both
 *                             accum_lock and state_lock.
 *                           - Can be read while holding either lock.
 *                           - Must stay in sync with enable_map.
 * @scratch_map:            Scratch enable map, used as temporary enable map
 *                          storage during dumps.
 *                           - Must only be read or modified while holding
 *                             accum_lock.
 * @accum_buf:              Accumulation buffer, where dumps will be accumulated
 *                          into on transition to a disable state.
 *                           - Must only be read or modified while holding
 *                             accum_lock.
 * @accumulated:            True if the accumulation buffer has been accumulated
 *                          into and not subsequently read from yet, else false.
 *                           - Must only be read or modified while holding
 *                             accum_lock.
 * @ts_last_dump_ns:        Timestamp (ns) of the end time of the most recent
 *                          dump that was requested by the user.
 *                           - Must only be read or modified while holding
 *                             accum_lock.
 */
struct kbase_hwcnt_accumulator {
	struct kbase_hwcnt_backend *backend;
	enum kbase_hwcnt_accum_state state;
	struct kbase_hwcnt_enable_map enable_map;
	bool enable_map_any_enabled;
	struct kbase_hwcnt_enable_map scratch_map;
	struct kbase_hwcnt_dump_buffer accum_buf;
	bool accumulated;
	u64 ts_last_dump_ns;
};

/**
 * struct kbase_hwcnt_context - Hardware counter context structure.
 * @iface:         Pointer to hardware counter backend interface.
 * @state_lock:    Spinlock protecting state.
 * @disable_count: Disable count of the context. Initialised to 1.
 *                 Decremented when the accumulator is acquired, and incremented
 *                 on release. Incremented on calls to
 *                 kbase_hwcnt_context_disable[_atomic], and decremented on
 *                 calls to kbase_hwcnt_context_enable.
 *                  - Must only be read or modified while holding state_lock.
 * @accum_lock:    Mutex protecting accumulator.
 * @accum_inited:  Flag to prevent concurrent accumulator initialisation and/or
 *                 termination. Set to true before accumulator initialisation,
 *                 and false after accumulator termination.
 *                  - Must only be modified while holding both accum_lock and
 *                    state_lock.
 *                  - Can be read while holding either lock.
 * @accum:         Hardware counter accumulator structure.
 */
struct kbase_hwcnt_context {
	const struct kbase_hwcnt_backend_interface *iface;
	spinlock_t state_lock;
	size_t disable_count;
	struct mutex accum_lock;
	bool accum_inited;
	struct kbase_hwcnt_accumulator accum;
};

int kbase_hwcnt_context_init(
	const struct kbase_hwcnt_backend_interface *iface,
	struct kbase_hwcnt_context **out_hctx)
{
	struct kbase_hwcnt_context *hctx = NULL;

	if (!iface || !out_hctx)
		return -EINVAL;

	hctx = kzalloc(sizeof(*hctx), GFP_KERNEL);
	if (!hctx)
		return -ENOMEM;

	hctx->iface = iface;
	spin_lock_init(&hctx->state_lock);
	hctx->disable_count = 1;
	mutex_init(&hctx->accum_lock);
	hctx->accum_inited = false;

	*out_hctx = hctx;

	return 0;
}
KBASE_EXPORT_TEST_API(kbase_hwcnt_context_init);

void kbase_hwcnt_context_term(struct kbase_hwcnt_context *hctx)
{
	if (!hctx)
		return;

	/* Make sure we didn't leak the accumulator */
	WARN_ON(hctx->accum_inited);
	kfree(hctx);
}
KBASE_EXPORT_TEST_API(kbase_hwcnt_context_term);

/**
 * kbasep_hwcnt_accumulator_term() - Terminate the accumulator for the context.
 * @hctx: Non-NULL pointer to hardware counter context.
 */
static void kbasep_hwcnt_accumulator_term(struct kbase_hwcnt_context *hctx)
{
	WARN_ON(!hctx);
	WARN_ON(!hctx->accum_inited);

	kbase_hwcnt_enable_map_free(&hctx->accum.scratch_map);
	kbase_hwcnt_dump_buffer_free(&hctx->accum.accum_buf);
	kbase_hwcnt_enable_map_free(&hctx->accum.enable_map);
	hctx->iface->term(hctx->accum.backend);
	memset(&hctx->accum, 0, sizeof(hctx->accum));
}

/**
 * kbasep_hwcnt_accumulator_init() - Initialise the accumulator for the context.
 * @hctx: Non-NULL pointer to hardware counter context.
 *
 * Return: 0 on success, else error code.
 */
static int kbasep_hwcnt_accumulator_init(struct kbase_hwcnt_context *hctx)
{
	int errcode;

	WARN_ON(!hctx);
	WARN_ON(!hctx->accum_inited);

	errcode = hctx->iface->init(
		hctx->iface->info, &hctx->accum.backend);
	if (errcode)
		goto error;

	hctx->accum.state = ACCUM_STATE_ERROR;

	errcode = kbase_hwcnt_enable_map_alloc(
		hctx->iface->metadata, &hctx->accum.enable_map);
	if (errcode)
		goto error;

	hctx->accum.enable_map_any_enabled = false;

	errcode = kbase_hwcnt_dump_buffer_alloc(
		hctx->iface->metadata, &hctx->accum.accum_buf);
	if (errcode)
		goto error;

	errcode = kbase_hwcnt_enable_map_alloc(
		hctx->iface->metadata, &hctx->accum.scratch_map);
	if (errcode)
		goto error;

	hctx->accum.accumulated = false;

	hctx->accum.ts_last_dump_ns =
		hctx->iface->timestamp_ns(hctx->accum.backend);

	return 0;

error:
	kbasep_hwcnt_accumulator_term(hctx);
	return errcode;
}

/**
 * kbasep_hwcnt_accumulator_disable() - Transition the accumulator into the
 *                                      disabled state, from the enabled or
 *                                      error states.
 * @hctx:       Non-NULL pointer to hardware counter context.
 * @accumulate: True if we should accumulate before disabling, else false.
 */
static void kbasep_hwcnt_accumulator_disable(
	struct kbase_hwcnt_context *hctx, bool accumulate)
{
	int errcode = 0;
	bool backend_enabled = false;
	struct kbase_hwcnt_accumulator *accum;
	unsigned long flags;

	WARN_ON(!hctx);
	lockdep_assert_held(&hctx->accum_lock);
	WARN_ON(!hctx->accum_inited);

	accum = &hctx->accum;

	spin_lock_irqsave(&hctx->state_lock, flags);

	WARN_ON(hctx->disable_count != 0);
	WARN_ON(hctx->accum.state == ACCUM_STATE_DISABLED);

	if ((hctx->accum.state == ACCUM_STATE_ENABLED) &&
	    (accum->enable_map_any_enabled))
		backend_enabled = true;

	if (!backend_enabled)
		hctx->accum.state = ACCUM_STATE_DISABLED;

	spin_unlock_irqrestore(&hctx->state_lock, flags);

	/* Early out if the backend is not already enabled */
	if (!backend_enabled)
		return;

	if (!accumulate)
		goto disable;

	/* Try and accumulate before disabling */
	errcode = hctx->iface->dump_request(accum->backend);
	if (errcode)
		goto disable;

	errcode = hctx->iface->dump_wait(accum->backend);
	if (errcode)
		goto disable;

	errcode = hctx->iface->dump_get(accum->backend,
		&accum->accum_buf, &accum->enable_map, accum->accumulated);
	if (errcode)
		goto disable;

	accum->accumulated = true;

disable:
	hctx->iface->dump_disable(accum->backend);

	/* Regardless of any errors during the accumulate, put the accumulator
	 * in the disabled state.
	 */
	spin_lock_irqsave(&hctx->state_lock, flags);

	hctx->accum.state = ACCUM_STATE_DISABLED;

	spin_unlock_irqrestore(&hctx->state_lock, flags);
}

/**
 * kbasep_hwcnt_accumulator_enable() - Transition the accumulator into the
 *                                     enabled state, from the disabled state.
 * @hctx: Non-NULL pointer to hardware counter context.
 */
static void kbasep_hwcnt_accumulator_enable(struct kbase_hwcnt_context *hctx)
{
	int errcode = 0;
	struct kbase_hwcnt_accumulator *accum;

	WARN_ON(!hctx);
	lockdep_assert_held(&hctx->state_lock);
	WARN_ON(!hctx->accum_inited);
	WARN_ON(hctx->accum.state != ACCUM_STATE_DISABLED);

	accum = &hctx->accum;

	/* The backend only needs enabling if any counters are enabled */
	if (accum->enable_map_any_enabled)
		errcode = hctx->iface->dump_enable_nolock(
			accum->backend, &accum->enable_map);

	if (!errcode)
		accum->state = ACCUM_STATE_ENABLED;
	else
		accum->state = ACCUM_STATE_ERROR;
}

/**
 * kbasep_hwcnt_accumulator_dump() - Perform a dump with the most up-to-date
 *                                   values of enabled counters possible, and
 *                                   optionally update the set of enabled
 *                                   counters.
 * @hctx :       Non-NULL pointer to the hardware counter context
 * @ts_start_ns: Non-NULL pointer where the start timestamp of the dump will
 *               be written out to on success
 * @ts_end_ns:   Non-NULL pointer where the end timestamp of the dump will
 *               be written out to on success
 * @dump_buf:    Pointer to the buffer where the dump will be written out to on
 *               success. If non-NULL, must have the same metadata as the
 *               accumulator. If NULL, the dump will be discarded.
 * @new_map:     Pointer to the new counter enable map. If non-NULL, must have
 *               the same metadata as the accumulator. If NULL, the set of
 *               enabled counters will be unchanged.
 */
static int kbasep_hwcnt_accumulator_dump(
	struct kbase_hwcnt_context *hctx,
	u64 *ts_start_ns,
	u64 *ts_end_ns,
	struct kbase_hwcnt_dump_buffer *dump_buf,
	const struct kbase_hwcnt_enable_map *new_map)
{
	int errcode = 0;
	unsigned long flags;
	enum kbase_hwcnt_accum_state state;
	bool dump_requested = false;
	bool dump_written = false;
	bool cur_map_any_enabled;
	struct kbase_hwcnt_enable_map *cur_map;
	bool new_map_any_enabled = false;
	u64 dump_time_ns;
	struct kbase_hwcnt_accumulator *accum;

	WARN_ON(!hctx);
	WARN_ON(!ts_start_ns);
	WARN_ON(!ts_end_ns);
	WARN_ON(dump_buf && (dump_buf->metadata != hctx->iface->metadata));
	WARN_ON(new_map && (new_map->metadata != hctx->iface->metadata));
	WARN_ON(!hctx->accum_inited);
	lockdep_assert_held(&hctx->accum_lock);

	accum = &hctx->accum;
	cur_map = &accum->scratch_map;

	/* Save out info about the current enable map */
	cur_map_any_enabled = accum->enable_map_any_enabled;
	kbase_hwcnt_enable_map_copy(cur_map, &accum->enable_map);

	if (new_map)
		new_map_any_enabled =
			kbase_hwcnt_enable_map_any_enabled(new_map);

	/*
	 * We're holding accum_lock, so the accumulator state might transition
	 * from disabled to enabled during this function (as enabling is lock
	 * free), but it will never disable (as disabling needs to hold the
	 * accum_lock), nor will it ever transition from enabled to error (as
	 * an enable while we're already enabled is impossible).
	 *
	 * If we're already disabled, we'll only look at the accumulation buffer
	 * rather than do a real dump, so a concurrent enable does not affect
	 * us.
	 *
	 * If a concurrent enable fails, we might transition to the error
	 * state, but again, as we're only looking at the accumulation buffer,
	 * it's not an issue.
	 */
	spin_lock_irqsave(&hctx->state_lock, flags);

	state = accum->state;

	/*
	 * Update the new map now, such that if an enable occurs during this
	 * dump then that enable will set the new map. If we're already enabled,
	 * then we'll do it ourselves after the dump.
	 */
	if (new_map) {
		kbase_hwcnt_enable_map_copy(
			&accum->enable_map, new_map);
		accum->enable_map_any_enabled = new_map_any_enabled;
	}

	spin_unlock_irqrestore(&hctx->state_lock, flags);

	/* Error state, so early out. No need to roll back any map updates */
	if (state == ACCUM_STATE_ERROR)
		return -EIO;

	/* Initiate the dump if the backend is enabled. */
	if ((state == ACCUM_STATE_ENABLED) && cur_map_any_enabled) {
		/* Disable pre-emption, to make the timestamp as accurate as
		 * possible.
		 */
		preempt_disable();
		{
			dump_time_ns = hctx->iface->timestamp_ns(
				accum->backend);
			if (dump_buf) {
				errcode = hctx->iface->dump_request(
					accum->backend);
				dump_requested = true;
			} else {
				errcode = hctx->iface->dump_clear(
					accum->backend);
			}
		}
		preempt_enable();
		if (errcode)
			goto error;
	} else {
		dump_time_ns = hctx->iface->timestamp_ns(accum->backend);
	}

	/* Copy any accumulation into the dest buffer */
	if (accum->accumulated && dump_buf) {
		kbase_hwcnt_dump_buffer_copy(
			dump_buf, &accum->accum_buf, cur_map);
		dump_written = true;
	}

	/* Wait for any requested dumps to complete */
	if (dump_requested) {
		WARN_ON(state != ACCUM_STATE_ENABLED);
		errcode = hctx->iface->dump_wait(accum->backend);
		if (errcode)
			goto error;
	}

	/* If we're enabled and there's a new enable map, change the enabled set
	 * as soon after the dump has completed as possible.
	 */
	if ((state == ACCUM_STATE_ENABLED) && new_map) {
		/* Backend is only enabled if there were any enabled counters */
		if (cur_map_any_enabled)
			hctx->iface->dump_disable(accum->backend);

		/* (Re-)enable the backend if the new map has enabled counters.
		 * No need to acquire the spinlock, as concurrent enable while
		 * we're already enabled and holding accum_lock is impossible.
		 */
		if (new_map_any_enabled) {
			errcode = hctx->iface->dump_enable(
				accum->backend, new_map);
			if (errcode)
				goto error;
		}
	}

	/* Copy, accumulate, or zero into the dest buffer to finish */
	if (dump_buf) {
		/* If we dumped, copy or accumulate it into the destination */
		if (dump_requested) {
			WARN_ON(state != ACCUM_STATE_ENABLED);
			errcode = hctx->iface->dump_get(
				accum->backend,
				dump_buf,
				cur_map,
				dump_written);
			if (errcode)
				goto error;
			dump_written = true;
		}

		/* If we've not written anything into the dump buffer so far, it
		 * means there was nothing to write. Zero any enabled counters.
		 */
		if (!dump_written)
			kbase_hwcnt_dump_buffer_zero(dump_buf, cur_map);
	}

	/* Write out timestamps */
	*ts_start_ns = accum->ts_last_dump_ns;
	*ts_end_ns = dump_time_ns;

	accum->accumulated = false;
	accum->ts_last_dump_ns = dump_time_ns;

	return 0;
error:
	/* An error was only physically possible if the backend was enabled */
	WARN_ON(state != ACCUM_STATE_ENABLED);

	/* Disable the backend, and transition to the error state */
	hctx->iface->dump_disable(accum->backend);
	spin_lock_irqsave(&hctx->state_lock, flags);

	accum->state = ACCUM_STATE_ERROR;

	spin_unlock_irqrestore(&hctx->state_lock, flags);

	return errcode;
}

/**
 * kbasep_hwcnt_context_disable() - Increment the disable count of the context.
 * @hctx:       Non-NULL pointer to hardware counter context.
 * @accumulate: True if we should accumulate before disabling, else false.
 */
static void kbasep_hwcnt_context_disable(
	struct kbase_hwcnt_context *hctx, bool accumulate)
{
	unsigned long flags;

	WARN_ON(!hctx);
	lockdep_assert_held(&hctx->accum_lock);

	if (!kbase_hwcnt_context_disable_atomic(hctx)) {
		kbasep_hwcnt_accumulator_disable(hctx, accumulate);

		spin_lock_irqsave(&hctx->state_lock, flags);

		/* Atomic disable failed and we're holding the mutex, so current
		 * disable count must be 0.
		 */
		WARN_ON(hctx->disable_count != 0);
		hctx->disable_count++;

		spin_unlock_irqrestore(&hctx->state_lock, flags);
	}
}

int kbase_hwcnt_accumulator_acquire(
	struct kbase_hwcnt_context *hctx,
	struct kbase_hwcnt_accumulator **accum)
{
	int errcode = 0;
	unsigned long flags;

	if (!hctx || !accum)
		return -EINVAL;

	mutex_lock(&hctx->accum_lock);
	spin_lock_irqsave(&hctx->state_lock, flags);

	if (!hctx->accum_inited)
		/* Set accum initing now to prevent concurrent init */
		hctx->accum_inited = true;
	else
		/* Already have an accum, or already being inited */
		errcode = -EBUSY;

	spin_unlock_irqrestore(&hctx->state_lock, flags);
	mutex_unlock(&hctx->accum_lock);

	if (errcode)
		return errcode;

	errcode = kbasep_hwcnt_accumulator_init(hctx);

	if (errcode) {
		mutex_lock(&hctx->accum_lock);
		spin_lock_irqsave(&hctx->state_lock, flags);

		hctx->accum_inited = false;

		spin_unlock_irqrestore(&hctx->state_lock, flags);
		mutex_unlock(&hctx->accum_lock);

		return errcode;
	}

	spin_lock_irqsave(&hctx->state_lock, flags);

	WARN_ON(hctx->disable_count == 0);
	WARN_ON(hctx->accum.enable_map_any_enabled);

	/* Decrement the disable count to allow the accumulator to be accessible
	 * now that it's fully constructed.
	 */
	hctx->disable_count--;

	/*
	 * Make sure the accumulator is initialised to the correct state.
	 * Regardless of initial state, counters don't need to be enabled via
	 * the backend, as the initial enable map has no enabled counters.
	 */
	hctx->accum.state = (hctx->disable_count == 0) ?
		ACCUM_STATE_ENABLED :
		ACCUM_STATE_DISABLED;

	spin_unlock_irqrestore(&hctx->state_lock, flags);

	*accum = &hctx->accum;

	return 0;
}
KBASE_EXPORT_TEST_API(kbase_hwcnt_accumulator_acquire);

void kbase_hwcnt_accumulator_release(struct kbase_hwcnt_accumulator *accum)
{
	unsigned long flags;
	struct kbase_hwcnt_context *hctx;

	if (!accum)
		return;

	hctx = container_of(accum, struct kbase_hwcnt_context, accum);

	mutex_lock(&hctx->accum_lock);

	/* Double release is a programming error */
	WARN_ON(!hctx->accum_inited);

	/* Disable the context to ensure the accumulator is inaccesible while
	 * we're destroying it. This performs the corresponding disable count
	 * increment to the decrement done during acquisition.
	 */
	kbasep_hwcnt_context_disable(hctx, false);

	mutex_unlock(&hctx->accum_lock);

	kbasep_hwcnt_accumulator_term(hctx);

	mutex_lock(&hctx->accum_lock);
	spin_lock_irqsave(&hctx->state_lock, flags);

	hctx->accum_inited = false;

	spin_unlock_irqrestore(&hctx->state_lock, flags);
	mutex_unlock(&hctx->accum_lock);
}
KBASE_EXPORT_TEST_API(kbase_hwcnt_accumulator_release);

void kbase_hwcnt_context_disable(struct kbase_hwcnt_context *hctx)
{
	if (WARN_ON(!hctx))
		return;

	/* Try and atomically disable first, so we can avoid locking the mutex
	 * if we don't need to.
	 */
	if (kbase_hwcnt_context_disable_atomic(hctx))
		return;

	mutex_lock(&hctx->accum_lock);

	kbasep_hwcnt_context_disable(hctx, true);

	mutex_unlock(&hctx->accum_lock);
}
KBASE_EXPORT_TEST_API(kbase_hwcnt_context_disable);

bool kbase_hwcnt_context_disable_atomic(struct kbase_hwcnt_context *hctx)
{
	unsigned long flags;
	bool atomic_disabled = false;

	if (WARN_ON(!hctx))
		return false;

	spin_lock_irqsave(&hctx->state_lock, flags);

	if (!WARN_ON(hctx->disable_count == SIZE_MAX)) {
		/*
		 * If disable count is non-zero, we can just bump the disable
		 * count.
		 *
		 * Otherwise, we can't disable in an atomic context.
		 */
		if (hctx->disable_count != 0) {
			hctx->disable_count++;
			atomic_disabled = true;
		}
	}

	spin_unlock_irqrestore(&hctx->state_lock, flags);

	return atomic_disabled;
}
KBASE_EXPORT_TEST_API(kbase_hwcnt_context_disable_atomic);

void kbase_hwcnt_context_enable(struct kbase_hwcnt_context *hctx)
{
	unsigned long flags;

	if (WARN_ON(!hctx))
		return;

	spin_lock_irqsave(&hctx->state_lock, flags);

	if (!WARN_ON(hctx->disable_count == 0)) {
		if (hctx->disable_count == 1)
			kbasep_hwcnt_accumulator_enable(hctx);

		hctx->disable_count--;
	}

	spin_unlock_irqrestore(&hctx->state_lock, flags);
}
KBASE_EXPORT_TEST_API(kbase_hwcnt_context_enable);

const struct kbase_hwcnt_metadata *kbase_hwcnt_context_metadata(
	struct kbase_hwcnt_context *hctx)
{
	if (!hctx)
		return NULL;

	return hctx->iface->metadata;
}
KBASE_EXPORT_TEST_API(kbase_hwcnt_context_metadata);

int kbase_hwcnt_accumulator_set_counters(
	struct kbase_hwcnt_accumulator *accum,
	const struct kbase_hwcnt_enable_map *new_map,
	u64 *ts_start_ns,
	u64 *ts_end_ns,
	struct kbase_hwcnt_dump_buffer *dump_buf)
{
	int errcode;
	struct kbase_hwcnt_context *hctx;

	if (!accum || !new_map || !ts_start_ns || !ts_end_ns)
		return -EINVAL;

	hctx = container_of(accum, struct kbase_hwcnt_context, accum);

	if ((new_map->metadata != hctx->iface->metadata) ||
	    (dump_buf && (dump_buf->metadata != hctx->iface->metadata)))
		return -EINVAL;

	mutex_lock(&hctx->accum_lock);

	errcode = kbasep_hwcnt_accumulator_dump(
		hctx, ts_start_ns, ts_end_ns, dump_buf, new_map);

	mutex_unlock(&hctx->accum_lock);

	return errcode;
}
KBASE_EXPORT_TEST_API(kbase_hwcnt_accumulator_set_counters);

int kbase_hwcnt_accumulator_dump(
	struct kbase_hwcnt_accumulator *accum,
	u64 *ts_start_ns,
	u64 *ts_end_ns,
	struct kbase_hwcnt_dump_buffer *dump_buf)
{
	int errcode;
	struct kbase_hwcnt_context *hctx;

	if (!accum || !ts_start_ns || !ts_end_ns)
		return -EINVAL;

	hctx = container_of(accum, struct kbase_hwcnt_context, accum);

	if (dump_buf && (dump_buf->metadata != hctx->iface->metadata))
		return -EINVAL;

	mutex_lock(&hctx->accum_lock);

	errcode = kbasep_hwcnt_accumulator_dump(
		hctx, ts_start_ns, ts_end_ns, dump_buf, NULL);

	mutex_unlock(&hctx->accum_lock);

	return errcode;
}
KBASE_EXPORT_TEST_API(kbase_hwcnt_accumulator_dump);

u64 kbase_hwcnt_accumulator_timestamp_ns(struct kbase_hwcnt_accumulator *accum)
{
	struct kbase_hwcnt_context *hctx;

	if (WARN_ON(!accum))
		return 0;

	hctx = container_of(accum, struct kbase_hwcnt_context, accum);
	return hctx->iface->timestamp_ns(accum->backend);
}
