/* Copyright (c) 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/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/amba/bus.h>
#include <linux/topology.h>
#include <linux/of.h>
#include <linux/coresight.h>

#include "coresight-priv.h"

#define tgu_writel(drvdata, val, off)	__raw_writel((val), drvdata->base + off)
#define tgu_readl(drvdata, off)		__raw_readl(drvdata->base + off)

#define TGU_LOCK(drvdata)						\
do {									\
	mb(); /* ensure configuration take effect before we lock it */	\
	tgu_writel(drvdata, 0x0, CORESIGHT_LAR);			\
} while (0)
#define TGU_UNLOCK(drvdata)						\
do {									\
	tgu_writel(drvdata, CORESIGHT_UNLOCK, CORESIGHT_LAR);		\
	mb(); /* ensure unlock take effect before we configure */	\
} while (0)

#define TGU_CONTROL			0x0000
#define TIMER0_STATUS			0x0004
#define COUNTER0_STATUS			0x000C
#define TGU_STATUS			0x0014
#define TIMER0_COMPARE_STEP(n)		(0x0040 + 0x1D8 * n)
#define COUNTER0_COMPARE_STEP(n)	(0x0048 + 0x1D8 * n)
#define GROUP_REG_STEP(grp, reg, step)	(0x0074 + 0x60 * grp + 0x4 * reg + \
								 0x1D8 * step)
#define CONDITION_DECODE_STEP(m, n)	(0x0050 + 0x4 * m + 0x1D8 * n)
#define CONDITION_SELECT_STEP(m, n)	(0x0060 + 0x4 * m + 0x1D8 * n)
#define GROUP0				0x0074
#define GROUP1				0x00D4
#define GROUP2				0x0134
#define GROUP3				0x0194
#define TGU_LAR				0x0FB0

#define MAX_GROUP_SETS			256
#define MAX_GROUPS			4
#define MAX_CONDITION_SETS		64
#define MAX_TIMER_COUNTER_SETS		8

#define to_tgu_drvdata(c)		container_of(c, struct tgu_drvdata, tgu)

struct Trigger_group_data {
	unsigned long grpaddr;
	unsigned long value;
};

struct Trigger_condition_data {
	unsigned long condaddr;
	unsigned long value;
};

struct Trigger_select_data {
	unsigned long selectaddr;
	unsigned long value;
};

struct Trigger_timer_data {
	unsigned long timeraddr;
	unsigned long value;
};

struct Trigger_counter_data {
	unsigned long counteraddr;
	unsigned long value;
};
struct tgu_drvdata {
	void __iomem			*base;
	struct device			*dev;
	struct coresight_device		*csdev;
	struct clk			*clk;
	spinlock_t			spinlock;
	int				max_steps;
	int				max_conditions;
	int				max_regs;
	int				max_timer_counter;
	struct Trigger_group_data	*grp_data;
	struct Trigger_condition_data	*condition_data;
	struct Trigger_select_data	*select_data;
	struct Trigger_timer_data	*timer_data;
	struct Trigger_counter_data	*counter_data;
	int				grp_refcnt;
	int				cond_refcnt;
	int				select_refcnt;
	int				timer_refcnt;
	int				counter_refcnt;
	bool				enable;
};

static ssize_t enable_tgu(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t size)
{
	unsigned long value;
	struct tgu_drvdata *drvdata = dev_get_drvdata(dev->parent);
	int ret, i, j;

	if (kstrtoul(buf, 16, &value))
		return -EINVAL;

	/* Enable clock */
	ret = pm_runtime_get_sync(drvdata->dev);
	if (ret)
		return ret;

	spin_lock(&drvdata->spinlock);
	/* Unlock the TGU LAR */
	TGU_UNLOCK(drvdata);

	if (value) {

		/* Disable TGU to program the triggers */
		tgu_writel(drvdata, 0, TGU_CONTROL);

		/* program the TGU Group data for the desired use case*/

		for (i = 0; i <= drvdata->grp_refcnt; i++)
			tgu_writel(drvdata, drvdata->grp_data[i].value,
						drvdata->grp_data[i].grpaddr);

		/* program the unused Condition Decode registers NOT bits to 1*/
		for (i = 0; i <= drvdata->max_conditions; i++) {
			for (j = 0; j <= drvdata->max_steps; j++)
				tgu_writel(drvdata, 0x1000000,
						CONDITION_DECODE_STEP(i, j));
		}
		/* program the TGU Condition Decode for the desired use case*/
		for (i = 0; i <= drvdata->cond_refcnt; i++)
			tgu_writel(drvdata, drvdata->condition_data[i].value,
					drvdata->condition_data[i].condaddr);

		/* program the TGU Condition Select for the desired use case*/
		for (i = 0; i <= drvdata->select_refcnt; i++)
			tgu_writel(drvdata, drvdata->select_data[i].value,
					drvdata->select_data[i].selectaddr);

		/*  Timer and Counter Check */
		for (i = 0; i <= drvdata->timer_refcnt; i++)
			tgu_writel(drvdata, drvdata->timer_data[i].value,
					drvdata->timer_data[i].timeraddr);

		for (i = 0; i <= drvdata->counter_refcnt; i++)
			tgu_writel(drvdata, drvdata->counter_data[i].value,
					drvdata->counter_data[i].counteraddr);

		/* Enable TGU to program the triggers */
		tgu_writel(drvdata, 1, TGU_CONTROL);

		drvdata->enable = true;
		dev_dbg(dev, "Coresight-TGU enabled\n");

	} else {
		/* Disable TGU to program the triggers */
		tgu_writel(drvdata, 0, TGU_CONTROL);
		TGU_LOCK(drvdata);
		spin_unlock(&drvdata->spinlock);

		pm_runtime_put(drvdata->dev);
		dev_dbg(dev, "Coresight-TGU disabled\n");
	}

	TGU_LOCK(drvdata);
	spin_unlock(&drvdata->spinlock);
	return size;
}
static DEVICE_ATTR(enable_tgu, 0200, NULL, enable_tgu);

static ssize_t reset_tgu(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t size)
{
	unsigned long value;
	struct tgu_drvdata *drvdata = dev_get_drvdata(dev->parent);
	int ret;

	if (kstrtoul(buf, 16, &value))
		return -EINVAL;

	if (!drvdata->enable) {
		/* Enable clock */
		ret = pm_runtime_get_sync(drvdata->dev);
		if (ret)
			return ret;
	}

	spin_lock(&drvdata->spinlock);
	/* Unlock the TGU LAR */
	TGU_UNLOCK(drvdata);

	if (value) {
		/* Disable TGU to program the triggers */
		tgu_writel(drvdata, 0, TGU_CONTROL);

		/* Reset the Reference counters*/
		drvdata->grp_refcnt = 0;
		drvdata->cond_refcnt = 0;
		drvdata->select_refcnt = 0;
		drvdata->timer_refcnt = 0;
		drvdata->counter_refcnt = 0;

		dev_dbg(dev, "Coresight-TGU disabled\n");
	} else
		dev_dbg(dev, "Invalid input to reset the TGU\n");

	TGU_LOCK(drvdata);
	spin_unlock(&drvdata->spinlock);
	pm_runtime_put(drvdata->dev);
	return size;
}
static DEVICE_ATTR(reset_tgu, 0200, NULL, reset_tgu);

static ssize_t set_group(struct device *dev, struct device_attribute *attr,
						const char *buf, size_t size)
{
	struct tgu_drvdata *drvdata = dev_get_drvdata(dev->parent);
	int grp, reg, step;
	unsigned long value;

	if (drvdata->grp_refcnt >= MAX_GROUP_SETS) {
		dev_err(drvdata->dev, " Too many groups are being configured");
		return -EINVAL;
	}

	if (sscanf(buf, "%d %d %d %lx", &grp, &reg, &step, &value) != 4)
		return -EINVAL;

	spin_lock(&drvdata->spinlock);
	if ((grp <= MAX_GROUPS) && (reg <= drvdata->max_regs)) {
		drvdata->grp_data[drvdata->grp_refcnt].grpaddr =
						GROUP_REG_STEP(grp, reg, step);
		drvdata->grp_data[drvdata->grp_refcnt].value = value;
		drvdata->grp_refcnt++;
	} else
		dev_err(drvdata->dev, "Invalid group data\n");

	spin_unlock(&drvdata->spinlock);

	return size;
}
static DEVICE_ATTR(set_group, 0200, NULL, set_group);

static ssize_t tgu_set_condition(struct device *dev, struct device_attribute
					*attr, const char *buf, size_t size)
{
	struct tgu_drvdata *drvdata = dev_get_drvdata(dev->parent);
	unsigned long value;
	int cond, step;

	if (drvdata->cond_refcnt >= MAX_CONDITION_SETS) {
		dev_err(drvdata->dev, " Too many groups are being configured");
		return -EINVAL;
	}

	if (sscanf(buf, "%d %d %lx", &cond, &step, &value) != 3)
		return -EINVAL;

	spin_lock(&drvdata->spinlock);
	if ((cond <= drvdata->max_conditions) && (step <=
						drvdata->max_steps)) {
		drvdata->condition_data[drvdata->cond_refcnt].condaddr =
					CONDITION_DECODE_STEP(cond, step);
		drvdata->condition_data[drvdata->cond_refcnt].value = value;
		drvdata->cond_refcnt++;
	} else
		dev_err(drvdata->dev, "Invalid condition decode data\n");

	spin_unlock(&drvdata->spinlock);

	return size;
}
static DEVICE_ATTR(set_condition, 0200, NULL, tgu_set_condition);

static ssize_t tgu_set_select(struct device *dev, struct device_attribute *attr,
						const char *buf, size_t size)
{
	struct tgu_drvdata *drvdata = dev_get_drvdata(dev->parent);
	unsigned long value;
	int select, step;

	if (drvdata->select_refcnt >= MAX_CONDITION_SETS) {
		dev_err(drvdata->dev, " Too many groups are being configured");
		return -EINVAL;
	}

	if (sscanf(buf, "%d %d %lx", &select, &step, &value) != 3)
		return -EINVAL;

	spin_lock(&drvdata->spinlock);

	if ((select <= drvdata->max_conditions) && (step <=
					drvdata->max_steps)) {
		drvdata->select_data[drvdata->select_refcnt].selectaddr =
					CONDITION_SELECT_STEP(select, step);
		drvdata->select_data[drvdata->select_refcnt].value = value;
		drvdata->select_refcnt++;
	} else
		dev_err(drvdata->dev, "Invalid select decode data\n");

	spin_unlock(&drvdata->spinlock);

	return size;
}
static DEVICE_ATTR(set_select, 0200, NULL, tgu_set_select);

static ssize_t tgu_set_timers(struct device *dev, struct device_attribute *attr,
						const char *buf, size_t size)
{
	struct tgu_drvdata *drvdata = dev_get_drvdata(dev->parent);
	unsigned long value;
	int step;

	if (drvdata->select_refcnt >= MAX_TIMER_COUNTER_SETS) {
		dev_err(drvdata->dev, " Too many groups are being configured");
		return -EINVAL;
	}

	if (sscanf(buf, "%d %lx", &step, &value) != 2)
		return -EINVAL;

	spin_lock(&drvdata->spinlock);
	if (step <= drvdata->max_timer_counter) {
		drvdata->timer_data[drvdata->timer_refcnt].timeraddr =
						TIMER0_COMPARE_STEP(step);
		drvdata->timer_data[drvdata->timer_refcnt].value = value;
		drvdata->timer_refcnt++;
	} else
		dev_err(drvdata->dev, "Invalid TGU timer data\n");

	spin_unlock(&drvdata->spinlock);

	return size;
}
static DEVICE_ATTR(set_timer, 0200, NULL, tgu_set_timers);

static ssize_t tgu_set_counters(struct device *dev, struct device_attribute
					*attr, const char *buf, size_t size)
{
	struct tgu_drvdata *drvdata = dev_get_drvdata(dev->parent);
	unsigned long value;
	int step;

	if (drvdata->counter_refcnt >= MAX_TIMER_COUNTER_SETS) {
		dev_err(drvdata->dev, " Too many groups are being configured");
		return -EINVAL;
	}

	if (sscanf(buf, "%d %lx", &step, &value) != 2)
		return -EINVAL;

	spin_lock(&drvdata->spinlock);
	if (step <= drvdata->max_timer_counter) {
		drvdata->counter_data[drvdata->counter_refcnt].counteraddr =
						COUNTER0_COMPARE_STEP(step);
		drvdata->counter_data[drvdata->counter_refcnt].value = value;
		drvdata->counter_refcnt++;
	} else
		dev_err(drvdata->dev, "Invalid TGU counter data\n");

	spin_unlock(&drvdata->spinlock);

	return size;
}
static DEVICE_ATTR(set_counter, 0200, NULL, tgu_set_counters);

static struct attribute *tgu_attrs[] = {
	&dev_attr_enable_tgu.attr,
	&dev_attr_reset_tgu.attr,
	&dev_attr_set_group.attr,
	&dev_attr_set_condition.attr,
	&dev_attr_set_select.attr,
	&dev_attr_set_timer.attr,
	&dev_attr_set_counter.attr,
	NULL,
};

static struct attribute_group tgu_attr_grp = {
	.attrs = tgu_attrs,
};

static const struct attribute_group *tgu_attr_grps[] = {
	&tgu_attr_grp,
	NULL,
};

static int tgu_probe(struct amba_device *adev, const struct amba_id *id)
{
	int ret = 0;
	struct device *dev = &adev->dev;
	struct coresight_platform_data *pdata;
	struct tgu_drvdata *drvdata;
	struct coresight_desc *desc;

	pdata = of_get_coresight_platform_data(dev, adev->dev.of_node);
	if (IS_ERR(pdata))
		return PTR_ERR(pdata);
	adev->dev.platform_data = pdata;

	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
	if (!drvdata)
		return -ENOMEM;

	drvdata->dev = &adev->dev;

	dev_set_drvdata(dev, drvdata);

	drvdata->base = devm_ioremap_resource(dev, &adev->res);
	if (!drvdata->base)
		return -ENOMEM;

	spin_lock_init(&drvdata->spinlock);

	ret = of_property_read_u32(adev->dev.of_node, "tgu-steps",
						&drvdata->max_steps);
	if (ret)
		return -EINVAL;

	ret = of_property_read_u32(adev->dev.of_node, "tgu-conditions",
						&drvdata->max_conditions);
	if (ret)
		return -EINVAL;

	ret = of_property_read_u32(adev->dev.of_node, "tgu-regs",
							&drvdata->max_regs);
	if (ret)
		return -EINVAL;

	ret = of_property_read_u32(adev->dev.of_node, "tgu-timer-counters",
						&drvdata->max_timer_counter);
	if (ret)
		return -EINVAL;

	/* Alloc memory for Grps, Conditions and Steps */
	drvdata->grp_data = devm_kzalloc(dev, MAX_GROUP_SETS *
				       sizeof(*drvdata->grp_data),
				       GFP_KERNEL);
	if (!drvdata->grp_data)
		return -ENOMEM;

	drvdata->condition_data = devm_kzalloc(dev, MAX_CONDITION_SETS *
				       sizeof(*drvdata->condition_data),
				       GFP_KERNEL);

	if (!drvdata->condition_data)
		return -ENOMEM;

	drvdata->select_data = devm_kzalloc(dev, MAX_CONDITION_SETS *
				       sizeof(*drvdata->select_data),
				       GFP_KERNEL);
	if (!drvdata->select_data)
		return -ENOMEM;

	drvdata->timer_data = devm_kzalloc(dev, MAX_TIMER_COUNTER_SETS *
				       sizeof(*drvdata->timer_data),
				       GFP_KERNEL);
	if (!drvdata->timer_data)
		return -ENOMEM;

	drvdata->counter_data = devm_kzalloc(dev, MAX_TIMER_COUNTER_SETS *
				       sizeof(*drvdata->counter_data),
				       GFP_KERNEL);
	if (!drvdata->counter_data)
		return -ENOMEM;

	drvdata->enable = false;

	desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
	if (!desc) {
		ret = -ENOMEM;
		goto err;
	}
	desc->type = CORESIGHT_DEV_TYPE_NONE;
	desc->pdata = adev->dev.platform_data;
	desc->dev = &adev->dev;
	desc->groups = tgu_attr_grps;
	drvdata->csdev = coresight_register(desc);
	if (IS_ERR(drvdata->csdev)) {
		ret = PTR_ERR(drvdata->csdev);
		goto err;
	}

	pm_runtime_put(&adev->dev);
	dev_dbg(dev, "TGU initialized\n");
	return 0;
err:
	pm_runtime_put(&adev->dev);
	return ret;
}

static struct amba_id tgu_ids[] = {
	{
		.id	=	0x0003b999,
		.mask	=	0x0003ffff,
		.data	=	"TGU",
	},
	{ 0, 0},
};

static struct amba_driver tgu_driver = {
	.drv = {
		.name			=	"coresight-tgu",
		.owner			=	THIS_MODULE,
		.suppress_bind_attrs	=	true,
	},
	.probe		=	tgu_probe,
	.id_table	=	tgu_ids,
};

builtin_amba_driver(tgu_driver);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("CoreSight TGU driver");
