/* Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * 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.
 *
 */


#include <linux/types.h>
#include <linux/debugfs.h>
#include <drm/drm_print.h>

#include "a5xx_gpu.h"

static int pfp_print(struct msm_gpu *gpu, struct drm_printer *p)
{
	int i;

	drm_printf(p, "PFP state:\n");

	for (i = 0; i < 36; i++) {
		gpu_write(gpu, REG_A5XX_CP_PFP_STAT_ADDR, i);
		drm_printf(p, "  %02x: %08x\n", i,
			gpu_read(gpu, REG_A5XX_CP_PFP_STAT_DATA));
	}

	return 0;
}

static int me_print(struct msm_gpu *gpu, struct drm_printer *p)
{
	int i;

	drm_printf(p, "ME state:\n");

	for (i = 0; i < 29; i++) {
		gpu_write(gpu, REG_A5XX_CP_ME_STAT_ADDR, i);
		drm_printf(p, "  %02x: %08x\n", i,
			gpu_read(gpu, REG_A5XX_CP_ME_STAT_DATA));
	}

	return 0;
}

static int meq_print(struct msm_gpu *gpu, struct drm_printer *p)
{
	int i;

	drm_printf(p, "MEQ state:\n");
	gpu_write(gpu, REG_A5XX_CP_MEQ_DBG_ADDR, 0);

	for (i = 0; i < 64; i++) {
		drm_printf(p, "  %02x: %08x\n", i,
			gpu_read(gpu, REG_A5XX_CP_MEQ_DBG_DATA));
	}

	return 0;
}

static int roq_print(struct msm_gpu *gpu, struct drm_printer *p)
{
	int i;

	drm_printf(p, "ROQ state:\n");
	gpu_write(gpu, REG_A5XX_CP_ROQ_DBG_ADDR, 0);

	for (i = 0; i < 512 / 4; i++) {
		uint32_t val[4];
		int j;
		for (j = 0; j < 4; j++)
			val[j] = gpu_read(gpu, REG_A5XX_CP_ROQ_DBG_DATA);
		drm_printf(p, "  %02x: %08x %08x %08x %08x\n", i,
			val[0], val[1], val[2], val[3]);
	}

	return 0;
}

static int show(struct seq_file *m, void *arg)
{
	struct drm_info_node *node = (struct drm_info_node *) m->private;
	struct drm_device *dev = node->minor->dev;
	struct msm_drm_private *priv = dev->dev_private;
	struct drm_printer p = drm_seq_file_printer(m);
	int (*show)(struct msm_gpu *gpu, struct drm_printer *p) =
		node->info_ent->data;

	return show(priv->gpu, &p);
}

#define ENT(n) { .name = #n, .show = show, .data = n ##_print }
static struct drm_info_list a5xx_debugfs_list[] = {
	ENT(pfp),
	ENT(me),
	ENT(meq),
	ENT(roq),
};

/* for debugfs files that can be written to, we can't use drm helper: */
static int
reset_set(void *data, u64 val)
{
	struct drm_device *dev = data;
	struct msm_drm_private *priv = dev->dev_private;
	struct msm_gpu *gpu = priv->gpu;
	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);

	if (!capable(CAP_SYS_ADMIN))
		return -EINVAL;

	/* TODO do we care about trying to make sure the GPU is idle?
	 * Since this is just a debug feature limited to CAP_SYS_ADMIN,
	 * maybe it is fine to let the user keep both pieces if they
	 * try to reset an active GPU.
	 */

	mutex_lock(&dev->struct_mutex);

	release_firmware(adreno_gpu->fw[ADRENO_FW_PM4]);
	adreno_gpu->fw[ADRENO_FW_PM4] = NULL;

	release_firmware(adreno_gpu->fw[ADRENO_FW_PFP]);
	adreno_gpu->fw[ADRENO_FW_PFP] = NULL;

	if (a5xx_gpu->pm4_bo) {
		if (a5xx_gpu->pm4_iova)
			msm_gem_put_iova(a5xx_gpu->pm4_bo, gpu->aspace);
		drm_gem_object_unreference(a5xx_gpu->pm4_bo);
		a5xx_gpu->pm4_bo = NULL;
	}

	if (a5xx_gpu->pfp_bo) {
		if (a5xx_gpu->pfp_iova)
			msm_gem_put_iova(a5xx_gpu->pfp_bo, gpu->aspace);
		drm_gem_object_unreference(a5xx_gpu->pfp_bo);
		a5xx_gpu->pfp_bo = NULL;
	}

	gpu->needs_hw_init = true;

	pm_runtime_get_sync(&gpu->pdev->dev);
	gpu->funcs->recover(gpu);

	pm_runtime_put_sync(&gpu->pdev->dev);
	mutex_unlock(&dev->struct_mutex);

	return 0;
}

DEFINE_SIMPLE_ATTRIBUTE(reset_fops, NULL, reset_set, "%llx\n");


int a5xx_debugfs_init(struct msm_gpu *gpu, struct drm_minor *minor)
{
	struct drm_device *dev;
	struct dentry *ent;
	int ret;

	if (!minor)
		return 0;

	dev = minor->dev;

	ret = drm_debugfs_create_files(a5xx_debugfs_list,
			ARRAY_SIZE(a5xx_debugfs_list),
			minor->debugfs_root, minor);

	if (ret) {
		dev_err(dev->dev, "could not install a5xx_debugfs_list\n");
		return ret;
	}

	ent = debugfs_create_file("reset", S_IWUGO,
		minor->debugfs_root,
		dev, &reset_fops);
	if (!ent)
		return -ENOMEM;

	return 0;
}
