// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
 * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
 */

#include <linux/module.h>

#include <trace/events/meson_atrace.h>
#include <linux/device/class.h>

static u64 atrace_tag;

#define TAG_INFO(name) \
	{ #name,  KERNEL_ATRACE_TAG_ ## name }

struct {
	char *name;
	int tag;
} tag_info[] = {
	TAG_INFO(VIDEO),
	TAG_INFO(CODEC_MM),
	TAG_INFO(VDEC),
	TAG_INFO(TSYNC),
	TAG_INFO(IONVIDEO),
	TAG_INFO(AMLVIDEO),
	TAG_INFO(VIDEO_COMPOSER),
	TAG_INFO(V4L2),
	TAG_INFO(CPUFREQ),
	TAG_INFO(MSYNC),
	TAG_INFO(DEMUX),
	TAG_INFO(MEDIA_SYNC),
	TAG_INFO(DDR_BW),
	TAG_INFO(DIM),
	{ NULL, 0 }
};

int get_atrace_tag_enabled(unsigned short tag)
{
	if (tag == KERNEL_ATRACE_TAG_ALL)
		return 1;
	return atrace_tag & (1 << tag);
}
EXPORT_SYMBOL(get_atrace_tag_enabled);

void set_atrace_tag_enabled(unsigned short tag, int enable)
{
	if (enable)
		atrace_tag |= (u64)1 << tag;
	else
		atrace_tag &= ~((u64)1 << tag);
}
EXPORT_SYMBOL(set_atrace_tag_enabled);

static ssize_t show_atrace_tag(const struct class *class,
			const struct class_attribute *attr,
			char *buf)
{
	ssize_t size = 0;
	int i;

	for (i = 0; i < ARRAY_SIZE(tag_info) && tag_info[i].name; i++) {
		size += sprintf(buf + size, "%2d %s %s\n",
			tag_info[i].tag, tag_info[i].name,
			get_atrace_tag_enabled(tag_info[i].tag) ? "ON" : "OFF");
	}

	return size;
}

static ssize_t store_atrace_tag(const struct class *class,
			const struct class_attribute *attr,
			const char *buf, size_t size)
{
	unsigned int tag;
	ssize_t r;

	r = kstrtouint(buf, 0, &tag);

	if (r != 0)
		return -EINVAL;
	if (tag < KERNEL_ATRACE_TAG_MAX)
		set_atrace_tag_enabled(tag, !get_atrace_tag_enabled(tag));

	return size;
}

static struct class_attribute debug_attrs[] = {
	__ATTR(atrace_tag, 0664, show_atrace_tag, store_atrace_tag),
	__ATTR_NULL
};

static struct attribute *debug_class_attrs[] = {
	&debug_attrs[0].attr,
	NULL
};

ATTRIBUTE_GROUPS(debug_class);

static struct class debug_class = {
		.name = "debug",
		.class_groups = debug_class_groups,
};

int meson_atrace_init(void)
{
	int r;

	r = class_register(&debug_class);

	if (r) {
		pr_err("debug class create fail.\n");
		return r;
	}

	return 0;
}

static char *print_flags_type(unsigned int flags)
{
	if (flags & 1UL << KERNEL_ATRACE_COUNTER)
		return "C";
	else if (flags & 1UL << KERNEL_ATRACE_BEGIN)
		return "B";
	else if (flags & 1UL << KERNEL_ATRACE_END)
		return "E";
	else if (flags & 1UL << KERNEL_ATRACE_ASYNC_BEGIN)
		return "S";
	else if (flags & 1UL << KERNEL_ATRACE_ASYNC_END)
		return "F";

	return NULL;
}

static noinline void tracing_mark_write(char *buf)
{
	__trace_puts(_THIS_IP_, buf, strlen(buf));
}

void meson_atrace(int tag, const char *name, unsigned int flags,
	 unsigned long value)
{
	char buf[256];

	if (get_atrace_tag_enabled(tag)) {
		snprintf(buf, sizeof(buf), "%s|1|%s|%lu\n",
			print_flags_type(flags), name, value);
		tracing_mark_write(buf);
	}
}
EXPORT_SYMBOL(meson_atrace);

void __aml_trace_printk(unsigned long ip, const char *fmt, ...)
{
	int len = 0;
	char buf[1024];
	va_list ap;

	va_start(ap, fmt);
	len = vscnprintf(buf, sizeof(buf), fmt, ap);
	if (len > 0)
		__trace_puts(ip, buf, strlen(buf));
	va_end(ap);
}
EXPORT_SYMBOL(__aml_trace_printk);
