// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2010 Google, Inc.
 * Author: Erik Gilling <konkers@android.com>
 *
 * Copyright (C) 2011-2013 NVIDIA Corporation
 */

#include <linux/debugfs.h>
#include <linux/pm_runtime.h>
#include <linux/seq_file.h>
#include <linux/uaccess.h>

#include <linux/io.h>

#include "dev.h"
#include "debug.h"
#include "channel.h"

static DEFINE_MUTEX(debug_lock);

unsigned int host1x_debug_trace_cmdbuf;

static pid_t host1x_debug_force_timeout_pid;
static u32 host1x_debug_force_timeout_val;
static u32 host1x_debug_force_timeout_channel;

void host1x_debug_output(struct output *o, const char *fmt, ...)
{
	va_list args;
	int len;

	va_start(args, fmt);
	len = vscnprintf(o->buf, sizeof(o->buf), fmt, args);
	va_end(args);

	o->fn(o->ctx, o->buf, len, false);
}

void host1x_debug_cont(struct output *o, const char *fmt, ...)
{
	va_list args;
	int len;

	va_start(args, fmt);
	len = vscnprintf(o->buf, sizeof(o->buf), fmt, args);
	va_end(args);

	o->fn(o->ctx, o->buf, len, true);
}

static int show_channel(struct host1x_channel *ch, void *data, bool show_fifo)
{
	struct host1x *m = dev_get_drvdata(ch->dev->parent);
	struct output *o = data;
	int err;

	err = pm_runtime_resume_and_get(m->dev);
	if (err < 0)
		return err;

	mutex_lock(&ch->cdma.lock);
	mutex_lock(&debug_lock);

	if (show_fifo)
		host1x_hw_show_channel_fifo(m, ch, o);

	host1x_hw_show_channel_cdma(m, ch, o);

	mutex_unlock(&debug_lock);
	mutex_unlock(&ch->cdma.lock);

	pm_runtime_put(m->dev);

	return 0;
}

static void show_syncpts(struct host1x *m, struct output *o, bool show_all)
{
	unsigned long irqflags;
	struct list_head *pos;
	unsigned int i;
	int err;

	host1x_debug_output(o, "---- syncpts ----\n");

	err = pm_runtime_resume_and_get(m->dev);
	if (err < 0)
		return;

	for (i = 0; i < host1x_syncpt_nb_pts(m); i++) {
		u32 max = host1x_syncpt_read_max(m->syncpt + i);
		u32 min = host1x_syncpt_load(m->syncpt + i);
		unsigned int waiters = 0;

		spin_lock_irqsave(&m->syncpt[i].fences.lock, irqflags);
		list_for_each(pos, &m->syncpt[i].fences.list)
			waiters++;
		spin_unlock_irqrestore(&m->syncpt[i].fences.lock, irqflags);

		if (!kref_read(&m->syncpt[i].ref))
			continue;

		if (!show_all && !min && !max && !waiters)
			continue;

		host1x_debug_output(o,
				    "id %u (%s) min %d max %d (%d waiters)\n",
				    i, m->syncpt[i].name, min, max, waiters);
	}

	for (i = 0; i < host1x_syncpt_nb_bases(m); i++) {
		u32 base_val;

		base_val = host1x_syncpt_load_wait_base(m->syncpt + i);
		if (base_val)
			host1x_debug_output(o, "waitbase id %u val %d\n", i,
					    base_val);
	}

	pm_runtime_put(m->dev);

	host1x_debug_output(o, "\n");
}

static void show_all(struct host1x *m, struct output *o, bool show_fifo)
{
	unsigned int i;

	host1x_hw_show_mlocks(m, o);
	show_syncpts(m, o, true);
	host1x_debug_output(o, "---- channels ----\n");

	for (i = 0; i < m->info->nb_channels; ++i) {
		struct host1x_channel *ch = host1x_channel_get_index(m, i);

		if (ch) {
			show_channel(ch, o, show_fifo);
			host1x_channel_put(ch);
		}
	}
}

static int host1x_debug_all_show(struct seq_file *s, void *unused)
{
	struct output o = {
		.fn = write_to_seqfile,
		.ctx = s
	};

	show_all(s->private, &o, true);

	return 0;
}
DEFINE_SHOW_ATTRIBUTE(host1x_debug_all);

static int host1x_debug_show(struct seq_file *s, void *unused)
{
	struct output o = {
		.fn = write_to_seqfile,
		.ctx = s
	};

	show_all(s->private, &o, false);

	return 0;
}
DEFINE_SHOW_ATTRIBUTE(host1x_debug);

static void host1x_debugfs_init(struct host1x *host1x)
{
	struct dentry *de = debugfs_create_dir("tegra-host1x", NULL);

	/* Store the created entry */
	host1x->debugfs = de;

	debugfs_create_file("status", S_IRUGO, de, host1x, &host1x_debug_fops);
	debugfs_create_file("status_all", S_IRUGO, de, host1x,
			    &host1x_debug_all_fops);

	debugfs_create_u32("trace_cmdbuf", S_IRUGO|S_IWUSR, de,
			   &host1x_debug_trace_cmdbuf);

	host1x_hw_debug_init(host1x, de);

	debugfs_create_u32("force_timeout_pid", S_IRUGO|S_IWUSR, de,
			   &host1x_debug_force_timeout_pid);
	debugfs_create_u32("force_timeout_val", S_IRUGO|S_IWUSR, de,
			   &host1x_debug_force_timeout_val);
	debugfs_create_u32("force_timeout_channel", S_IRUGO|S_IWUSR, de,
			   &host1x_debug_force_timeout_channel);
}

static void host1x_debugfs_exit(struct host1x *host1x)
{
	debugfs_remove_recursive(host1x->debugfs);
}

void host1x_debug_init(struct host1x *host1x)
{
	if (IS_ENABLED(CONFIG_DEBUG_FS))
		host1x_debugfs_init(host1x);
}

void host1x_debug_deinit(struct host1x *host1x)
{
	if (IS_ENABLED(CONFIG_DEBUG_FS))
		host1x_debugfs_exit(host1x);
}

void host1x_debug_dump(struct host1x *host1x)
{
	struct output o = {
		.fn = write_to_printk
	};

	show_all(host1x, &o, true);
}
