// SPDX-License-Identifier: GPL-2.0
/*
 * 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;
}
