// SPDX-License-Identifier: GPL-2.0-only
/*
 * DSP usage stats
 *
 * Copyright (C) 2022 Google LLC
 */

#include <linux/device.h>

#include <gcip/gcip-usage-stats.h>

#include "gxp-config.h"
#include "gxp-mcu-platform.h"
#include "gxp-mcu.h"
#include "gxp-pm.h"
#include "gxp-usage-stats.h"

/* Core usage. */
static GCIP_USAGE_STATS_ATTR_RW(GCIP_USAGE_STATS_METRIC_TYPE_CORE_USAGE, 0, 0, dsp_usage_0, NULL,
				NULL);

static GCIP_USAGE_STATS_ATTR_RW(GCIP_USAGE_STATS_METRIC_TYPE_CORE_USAGE, 0, 1, dsp_usage_1, NULL,
				NULL);

static GCIP_USAGE_STATS_ATTR_RW(GCIP_USAGE_STATS_METRIC_TYPE_CORE_USAGE, 0, 2, dsp_usage_2, NULL,
				NULL);

/* Counter. */
static GCIP_USAGE_STATS_ATTR_RW(GCIP_USAGE_STATS_METRIC_TYPE_COUNTER,
				GCIP_USAGE_STATS_COUNTER_WORKLOAD,
				GCIP_USAGE_STATS_ATTR_ALL_SUBCOMPONENTS, dsp_workload_count, NULL,
				NULL);

static GCIP_USAGE_STATS_ATTR_RW(GCIP_USAGE_STATS_METRIC_TYPE_COUNTER,
				GCIP_USAGE_STATS_COUNTER_CONTEXT_SWITCHES,
				GCIP_USAGE_STATS_ATTR_ALL_SUBCOMPONENTS, context_switch_count, NULL,
				NULL);

static GCIP_USAGE_STATS_ATTR_RW(GCIP_USAGE_STATS_METRIC_TYPE_COUNTER,
				GCIP_USAGE_STATS_COUNTER_CONTEXT_PREEMPTIONS,
				GCIP_USAGE_STATS_ATTR_ALL_SUBCOMPONENTS, preempt_count, NULL, NULL);

/* Thread statistics. */
static GCIP_USAGE_STATS_ATTR_RW(GCIP_USAGE_STATS_METRIC_TYPE_THREAD_STATS, 0, 0, fw_thread_stats,
				NULL, NULL);

/* DVFS frequency info. */
static GCIP_USAGE_STATS_ATTR_RO(GCIP_USAGE_STATS_METRIC_TYPE_DVFS_FREQUENCY_INFO, 0, 0,
				scaling_available_frequencies, NULL);

static struct gcip_usage_stats_attr *attrs[] = {
	&gcip_usage_stats_attr_dsp_usage_0,
	&gcip_usage_stats_attr_dsp_usage_1,
	&gcip_usage_stats_attr_dsp_usage_2,
	&gcip_usage_stats_attr_dsp_workload_count,
	&gcip_usage_stats_attr_context_switch_count,
	&gcip_usage_stats_attr_preempt_count,
	&gcip_usage_stats_attr_fw_thread_stats,
	&gcip_usage_stats_attr_scaling_available_frequencies,
};

static int update_usage_kci(void *data)
{
	struct gxp_usage_stats *ustats = data;
	struct gxp_dev *gxp = ustats->gxp;
	struct gxp_mcu *mcu = &to_mcu_dev(gxp)->mcu;

	return gxp_kci_update_usage(&mcu->kci);
}

static int get_default_dvfs_freqs_num(void *data)
{
	return AUR_NUM_POWER_STATE;
}

static int get_default_dvfs_freq(int idx, void *data)
{
	if (idx >= AUR_NUM_POWER_STATE)
		return 0;
	return aur_power_state2rate[idx];
}

static const struct gcip_usage_stats_ops stats_ops = {
	.update_usage_kci = update_usage_kci,
	.get_default_dvfs_freqs_num = get_default_dvfs_freqs_num,
	.get_default_dvfs_freq = get_default_dvfs_freq,
};

void gxp_usage_stats_process_buffer(struct gxp_dev *gxp, void *buf)
{
	if (!gxp->usage_stats)
		return;
	gcip_usage_stats_process_buffer(&gxp->usage_stats->ustats, buf);
}

void gxp_usage_stats_init(struct gxp_dev *gxp)
{
	struct gxp_usage_stats *ustats;
	struct gcip_usage_stats_args args;
	int ret;

	ustats = devm_kzalloc(gxp->dev, sizeof(*gxp->usage_stats), GFP_KERNEL);
	if (!ustats)
		return;

	args.version = GXP_USAGE_METRIC_VERSION;
	args.dev = gxp->dev;
	args.ops = &stats_ops;
	args.attrs = attrs;
	args.num_attrs = ARRAY_SIZE(attrs);
	args.subcomponents = GXP_NUM_CORES;
	args.data = ustats;
	ustats->gxp = gxp;

	ret = gcip_usage_stats_init(&ustats->ustats, &args);
	if (ret) {
		dev_warn(gxp->dev, "failed to create the usage_stats attrs\n");
		devm_kfree(gxp->dev, ustats);
		return;
	}

	gxp->usage_stats = ustats;
}

void gxp_usage_stats_exit(struct gxp_dev *gxp)
{
	if (gxp->usage_stats) {
		gcip_usage_stats_exit(&gxp->usage_stats->ustats);
		devm_kfree(gxp->dev, gxp->usage_stats);
	}
	gxp->usage_stats = NULL;
}
