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

#include <linux/version.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/printk.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/sysfs.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/sched/clock.h>
#include <linux/timer.h>
#include "ddr_bandwidth.h"
#include "dmc.h"

#define T_BUF_SIZE	(1024 * 1024 * 50)

static struct hrtimer ddr_hrtimer_timer;

static struct ddr_bandwidth *aml_db;

/* run time should be short */
static enum hrtimer_restart  ddr_hrtimer_handler(struct hrtimer *timer)
{
	static u64 index;

	hrtimer_start(&ddr_hrtimer_timer,
					ktime_set(0, aml_db->increase_tool.t_ns),
					HRTIMER_MODE_REL);
	memset(aml_db->increase_tool.buf_addr + index, 0, aml_db->increase_tool.once_size);
	index += aml_db->increase_tool.once_size;
	if ((index + aml_db->increase_tool.once_size) > T_BUF_SIZE)
		index = 0;

	return HRTIMER_RESTART;
}

static int __init ddr_hrtimer_init(void)
{
	hrtimer_init(&ddr_hrtimer_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	ddr_hrtimer_timer.function = ddr_hrtimer_handler;
	return 0;
}

static void ddr_hrtimer_cancel(void)
{
	hrtimer_cancel(&ddr_hrtimer_timer);
}

static int dual_dmc(struct ddr_bandwidth *db)
{
	if (db && (db->soc_feature & DUAL_DMC))
		return 1;
	return 0;
}

static int quad_dmc(struct ddr_bandwidth *db)
{
	if (db && (db->soc_feature & QUAD_DMC))
		return 1;
	return 0;
}

static void cal_ddr_usage(struct ddr_bandwidth *db, struct ddr_grant *dg)
{
	u64 mul, mbw; /* avoid overflow */
	unsigned long i, cnt, freq = 0, flags;

	if (db->mode == MODE_AUTODETECT) { /* ignore mali bandwidth */
		static int count;
		unsigned int grant = dg->all_grant;

		if (db->mali_port[0] >= 0)
			grant -= dg->channel_grant[0];
		if (db->mali_port[1] >= 0)
			grant -= dg->channel_grant[1];
		if (grant > db->threshold) {
			if (count >= 2) {
				if (db->busy == 0) {
					db->busy = 1;
					schedule_work(&db->work_bandwidth);
				}
			} else {
				count++;
			}
		} else if (count > 0) {
			if (count >= 2) {
				db->busy = 0;
				schedule_work(&db->work_bandwidth);
			}
			count = 0;
		}
		return;
	}
	if (db->ops && db->ops->get_freq)
		freq = db->ops->get_freq(db);
	cnt  = db->clock_count;
	if (freq) {
		/* calculate in KB */
		mbw  = (u64)freq * db->bytes_per_cycle * db->dmc_number;
		mbw /= 1024;	/* theoretic max bandwidth */
		mul  = dg->all_grant;
		mul *= freq;
		mul /= 1024;
		do_div(mul, cnt);
		if (mul >= mbw) {
			/* sample may overflow if irq tick changed, ignore it */
			pr_emerg("%s, bandwidth:%lld large than max :%lld\n",
				 __func__, mul, mbw);
			//return;
		}
		db->cur_sample.total_bandwidth = mul;
		mul *= 10000ULL;
		do_div(mul, mbw);
		db->cur_sample.total_usage = mul;
		db->cur_sample.tick = sched_clock();
		for (i = 0; i < db->channels; i++) {
			mul  = dg->channel_grant[i];
			mul *= freq;
			mul /= 1024;
			do_div(mul, cnt);
			db->cur_sample.bandwidth[i] = mul;
		}
	}

	if (db->stat_flag)  /* stop update usage stat if flag set */
		return;

	spin_lock_irqsave(&aml_db->lock, flags);
	/* update max sample */
	if (db->cur_sample.total_bandwidth > db->max_sample.total_bandwidth)
		memcpy(&db->max_sample, &db->cur_sample,
		       sizeof(struct ddr_bandwidth_sample));

	/* update usage statistics */
	db->usage_stat[db->cur_sample.total_usage / 1000]++;

	/* collect for average bandwidth calculate */
	db->avg.avg_bandwidth += db->cur_sample.total_bandwidth;
	db->avg.avg_usage     += db->cur_sample.total_usage;
	for (i = 0; i < db->channels; i++) {
		db->avg.avg_port[i]  += db->cur_sample.bandwidth[i];
		if (db->cur_sample.bandwidth[i] > db->avg.max_bandwidth[i])
			db->avg.max_bandwidth[i] = db->cur_sample.bandwidth[i];
	}
	db->avg.sample_count++;
	spin_unlock_irqrestore(&aml_db->lock, flags);
}

static irqreturn_t dmc_irq_handler(int irq, void *dev_instance)
{
	struct ddr_bandwidth *db;
	struct ddr_grant dg = {0};

	db = (struct ddr_bandwidth *)dev_instance;
	if (db->ops && db->ops->handle_irq) {
		if (!db->ops->handle_irq(db, &dg))
			cal_ddr_usage(db, &dg);
	}
	return IRQ_HANDLED;
}

unsigned int aml_get_ddr_usage(void)
{
	unsigned int ret = 0;

	if (aml_db)
		ret = aml_db->cur_sample.total_usage;

	return ret;
}
EXPORT_SYMBOL(aml_get_ddr_usage);

static char *find_port_name(int id)
{
	int i;

	if (!aml_db->real_ports || !aml_db->port_desc)
		return NULL;

	for (i = 0; i < aml_db->real_ports; i++) {
		if (aml_db->port_desc[i].port_id == id)
			return aml_db->port_desc[i].port_name;
	}
	return NULL;
}

static void clear_bandwidth_statistics(void)
{
	unsigned long flags;

	/* clear flag and start statistics */
	spin_lock_irqsave(&aml_db->lock, flags);
	memset(&aml_db->max_sample, 0, sizeof(struct ddr_bandwidth_sample));
	memset(aml_db->usage_stat, 0, 10 * sizeof(int));
	memset(&aml_db->avg, 0, sizeof(struct ddr_avg_bandwidth));
	spin_unlock_irqrestore(&aml_db->lock, flags);
}

static int format_port(char *buf, u64 port_mask)
{
	u64 t;
	int i, size = 0;
	char *name, dev;

	if (!port_mask)
		return 0;

	if (dual_dmc(aml_db) || quad_dmc(aml_db)) {
		for (i = 0; i < 3; i++) {
			dev = port_mask & 0xff;
			port_mask >>= 8;
			if (!dev)
				continue;
			name = find_port_name(dev);
			if (!name)
				continue;
			size += sprintf(buf + size, "      %s\n", name);
		}
	} else {
		for (i = 0; i < sizeof(u64) * 8; i++) {
			t = 1ULL << i;
			if (port_mask & t) {
				name = find_port_name(i);
				if (!name)
					continue;
				size += sprintf(buf + size, "      %s\n", name);
			}
		}
	}
	return size;
}

static ssize_t port_show(struct class *cla,
			 struct class_attribute *attr, char *buf)
{
	int s = 0, i;

	if (aml_db->ops && !aml_db->ops->config_range) {
		for (i = 0; i < aml_db->channels; i++) {
			s += sprintf(buf + s, "ch %d:%16llx: ports:\n",
					i, aml_db->port[i]);
			s += format_port(buf + s, aml_db->port[i]);
		}
		return s;
	}
	for (i = 0; i < aml_db->channels; i++) {
		s += sprintf(buf + s, "ch %d:%16llx, [%08lx-%08lx], ports:\n",
				i, aml_db->port[i],
				aml_db->range[i].start,
				aml_db->range[i].end);
		s += format_port(buf + s, aml_db->port[i]);
	}
	return s;
}

static int dual_dmc_port_set(struct ddr_bandwidth *db, int port, int ch)
{
	int i, t;
	u64 cur;

	cur = db->port[ch];
	for (i = 0; i < 3; i++) {
		t = cur & 0xff;
		cur >>= 8;
		if (!t)
			break;
	}
	if (i >= 3) {
		pr_err("each channel only support 3 ports\n");
		return -ERANGE;
	}
	port &= 0xff;
	db->port[ch] = (db->port[ch] | (port << (i * 8)));
	return 0;
}

static ssize_t port_store(struct class *cla,
			  struct class_attribute *attr,
			  const char *buf, size_t count)
{
	int ch = 0, port = 0, paras = -1;
	unsigned long start = 0xffffffff, end;

	paras = sscanf(buf, "%d:%d %lx-%lx", &ch, &port, &start, &end);
	if (paras < 4) {
		paras = sscanf(buf, "%d:%d", &ch, &port);
		if (paras < 2) {
			pr_info("invalid input:%s\n", buf);
			return count;
		}
	}
	if (ch >= MAX_CHANNEL || ch < 0 ||
	    (ch && aml_db->cpu_type < DMC_TYPE_GXTVBB) ||
	    port > MAX_PORTS) {
		pr_info("invalid channel %d or port %d\n", ch, port);
		return count;
	}

	if (aml_db->ops && aml_db->ops->config_port) {
		if (dual_dmc(aml_db) || quad_dmc(aml_db)) {
			if (port < 0) /* clear port set */
				aml_db->port[ch] = 0;
			else
				if (dual_dmc_port_set(aml_db, port, ch))
					return -ERANGE;
			aml_db->ops->config_port(aml_db, ch, aml_db->port[ch]);
		} else {
			if (port < 0) /* clear port set */
				aml_db->port[ch] = 0;
			else
				aml_db->port[ch] |= 1ULL << port;
			aml_db->ops->config_port(aml_db, ch, port);
		}
	}

	if (paras == 4 && aml_db->ops &&
		aml_db->ops->config_range && start != 0xffffffffffffffffULL) {
		aml_db->ops->config_range(aml_db, ch, start, end);
		aml_db->range[ch].start = start;
		aml_db->range[ch].end   = end;
	}

	return count;
}
static CLASS_ATTR_RW(port);

static ssize_t busy_show(struct class *cla,
			 struct class_attribute *attr, char *buf)
{
	return sprintf(buf, "%d\n", aml_db->busy);
}
static CLASS_ATTR_RO(busy);

static ssize_t threshold_show(struct class *cla,
			      struct class_attribute *attr, char *buf)
{
	return sprintf(buf, "%d\n",
			aml_db->threshold / aml_db->bytes_per_cycle
			/ (aml_db->clock_count / 10000));
}

static ssize_t threshold_store(struct class *cla,
			       struct class_attribute *attr,
			       const char *buf, size_t count)
{
	long val = 0;

	if (kstrtoul(buf, 10, &val)) {
		pr_info("invalid input:%s\n", buf);
		return 0;
	}

	if (val > 10000)
		val = 10000;
	aml_db->threshold = val * aml_db->bytes_per_cycle
			* (aml_db->clock_count / 10000);
	return count;
}
static CLASS_ATTR_RW(threshold);

static ssize_t mode_show(struct class *cla,
			 struct class_attribute *attr, char *buf)
{
	if (aml_db->mode == MODE_DISABLE)
		return sprintf(buf, "0: disable\n");
	else if (aml_db->mode == MODE_ENABLE)
		return sprintf(buf, "1: enable\n");
	else if (aml_db->mode == MODE_AUTODETECT)
		return sprintf(buf, "2: auto detect\n");
	return sprintf(buf, "\n");
}

static ssize_t mode_store(struct class *cla,
			  struct class_attribute *attr,
			  const char *buf, size_t count)
{
	long val = 0;

	if (kstrtoul(buf, 10, &val)) {
		pr_info("invalid input:%s\n", buf);
		return 0;
	}
	if (val > MODE_AUTODETECT || val < MODE_DISABLE)
		val = MODE_AUTODETECT;

	if (aml_db->mode == MODE_DISABLE && val != MODE_DISABLE) {
		int r = request_irq(aml_db->irq_num, dmc_irq_handler,
				IRQF_SHARED, "ddr_bandwidth", (void *)aml_db);
		if (r < 0) {
			pr_info("ddrbandwidth request irq failed\n");
			return count;
		}

		if (aml_db->ops->init)
			aml_db->ops->init(aml_db);
	} else if ((aml_db->mode != MODE_DISABLE) && (val == MODE_DISABLE)) {
		free_irq(aml_db->irq_num, (void *)aml_db);
		aml_db->cur_sample.total_usage = 0;
		aml_db->cur_sample.total_bandwidth = 0;
		aml_db->busy = 0;
		clear_bandwidth_statistics();
	}
	if (val == MODE_AUTODETECT && aml_db->ops &&
	    aml_db->ops->config_port && !(dual_dmc(aml_db) || quad_dmc(aml_db))) {
		if (aml_db->mali_port[0] >= 0) {
			aml_db->ops->config_port(aml_db, 0, aml_db->mali_port[0]);
			aml_db->port[0] = (1ULL << aml_db->mali_port[0]);
		}
		if (aml_db->mali_port[1] >= 0) {
			aml_db->ops->config_port(aml_db, 1, aml_db->mali_port[1]);
			aml_db->port[1] = (1ULL << aml_db->mali_port[1]);
		}
	}
	aml_db->mode = val;

	return count;
}
static CLASS_ATTR_RW(mode);

static ssize_t irq_clock_show(struct class *cla,
			      struct class_attribute *attr, char *buf)
{
	return sprintf(buf, "%d\n", aml_db->clock_count);
}

static ssize_t irq_clock_store(struct class *cla,
			       struct class_attribute *attr,
			       const char *buf, size_t count)
{
	long val = 0;

	if (kstrtoul(buf, 10, &val)) {
		pr_info("invalid input:%s\n", buf);
		return 0;
	}
	aml_db->threshold /= (aml_db->clock_count / 10000);
	aml_db->threshold *= (val / 10000);
	aml_db->clock_count = val;
	if (aml_db->ops && aml_db->ops->init)
		aml_db->ops->init(aml_db);
	return count;
}
static CLASS_ATTR_RW(irq_clock);

static ssize_t usage_stat_store(struct class *cla,
				struct class_attribute *attr,
				const char *buf, size_t count)
{
	int d = -1;

	if (kstrtoint(buf, 10, &d))
		return count;

	aml_db->stat_flag = d;
	if (d)
		return count;

	clear_bandwidth_statistics();
	return count;
}

static ssize_t usage_stat_show(struct class *cla,
			       struct class_attribute *attr, char *buf)
{
	size_t s = 0;
	int percent, rem, i;
	unsigned long long tick;
	unsigned long total_count = 0;
	struct ddr_avg_bandwidth tmp;
#define MAX_PREFIX "MAX bandwidth: %8d KB/s, usage: %2d.%02d%%"
#define AVG_PREFIX "AVG bandwidth: %8lld KB/s, usage: %2d.%02d%%"

	if (aml_db->mode != MODE_ENABLE)
		return sprintf(buf, "set mode to enable(1) first.\n");

	total_count = aml_db->avg.sample_count;
	if (!total_count)
		return sprintf(buf, "No sample, please wait...\n");

	/* show for max bandwidth */
	percent = aml_db->max_sample.total_usage / 100;
	rem     = aml_db->max_sample.total_usage % 100;
	tick    = aml_db->max_sample.tick;
	do_div(tick, 1000);
	s      += sprintf(buf + s, MAX_PREFIX ", tick:%lld us\n",
			  aml_db->max_sample.total_bandwidth,
			  percent, rem, tick);

	/* show for average bandwidth */
	memcpy(&tmp, &aml_db->avg, sizeof(tmp));
	do_div(tmp.avg_bandwidth, total_count);
	do_div(tmp.avg_usage,     total_count);
	for (i = 0; i < aml_db->channels; i++)
		do_div(tmp.avg_port[i], total_count);

	rem     = do_div(tmp.avg_usage, 100);
	percent = tmp.avg_usage,
	s      += sprintf(buf + s, AVG_PREFIX ", samples:%ld\n",
			  tmp.avg_bandwidth,
			  percent, rem, total_count);

	s += sprintf(buf + s, "\nbandwidth status for each channel\n");
	s += sprintf(buf + s, "ch,        %s, avg bw(KB/s), max bw(KB/s), %s\n",
		     "port mask", "bw@max sample(KB/s)");
	for (i = 0; i < aml_db->channels; i++) {
		s += sprintf(buf + s,
			     "%2d, %16llx,     %8lld,     %8ld,          %8d\n",
			     i, aml_db->port[i],
			     tmp.avg_port[i],
			     tmp.max_bandwidth[i],
			     aml_db->max_sample.bandwidth[i]);
	}

	/* show for usage statistics */
	s += sprintf(buf + s, "\nusage distribution:\n");
	s += sprintf(buf + s, "range,         count,  proportion\n");
	for (i = 0; i < 10; i++) {
		percent = aml_db->usage_stat[i] * 10000 / total_count;
		rem     = percent % 100;
		percent = percent / 100;
		s += sprintf(buf + s, "%2d%% ~ %3d%%: %8d,  %3d.%02d%%\n",
			     i * 10, (i + 1) * 10,
			     aml_db->usage_stat[i], percent, rem);
	}
	s += sprintf(buf + s, "\n");
	return s;
}
static CLASS_ATTR_RW(usage_stat);

static ssize_t bandwidth_show(struct class *cla,
			      struct class_attribute *attr, char *buf)
{
	size_t s = 0;
	int percent, rem, i;
	unsigned long long tick;
#define BANDWIDTH_PREFIX "Total bandwidth: %8d KB/s, usage: %2d.%02d%%\n"

	if (aml_db->mode != MODE_ENABLE)
		return sprintf(buf, "set mode to enable(1) first.\n");

	percent = aml_db->cur_sample.total_usage / 100;
	rem     = aml_db->cur_sample.total_usage % 100;
	tick    = aml_db->cur_sample.tick;
	do_div(tick, 1000);
	s      += sprintf(buf + s, BANDWIDTH_PREFIX,
			  aml_db->cur_sample.total_bandwidth,
			  percent, rem);

	for (i = 0; i < aml_db->channels; i++) {
		s += sprintf(buf + s, "ch:%d port:%16llx: %8d KB/s\n",
			     i, aml_db->port[i],
			     aml_db->cur_sample.bandwidth[i]);
	}
	return s;
}
static CLASS_ATTR_RO(bandwidth);

static ssize_t freq_show(struct class *cla,
			 struct class_attribute *attr, char *buf)
{
	unsigned long clk = 0;

	if (aml_db->ops && aml_db->ops->get_freq)
		clk = aml_db->ops->get_freq(aml_db);
	return sprintf(buf, "%ld MHz\n", clk / 1000000);
}
static CLASS_ATTR_RO(freq);

void dmc_set_urgent(unsigned int port, unsigned int type)
{
	unsigned int val = 0, addr = 0;

	if (aml_db->cpu_type < DMC_TYPE_G12A) {
		unsigned int port_reg[16] = {
			DMC_AXI0_CHAN_CTRL, DMC_AXI1_CHAN_CTRL,
			DMC_AXI2_CHAN_CTRL, DMC_AXI3_CHAN_CTRL,
			DMC_AXI4_CHAN_CTRL, DMC_AXI5_CHAN_CTRL,
			DMC_AXI6_CHAN_CTRL, DMC_AXI7_CHAN_CTRL,
			DMC_AM0_CHAN_CTRL, DMC_AM1_CHAN_CTRL,
			DMC_AM2_CHAN_CTRL, DMC_AM3_CHAN_CTRL,
			DMC_AM4_CHAN_CTRL, DMC_AM5_CHAN_CTRL,
			DMC_AM6_CHAN_CTRL, DMC_AM7_CHAN_CTRL,};

		if (port >= 16)
			return;
		addr = port_reg[port];
	} else {
		unsigned int port_reg[24] = {
			DMC_AXI0_G12_CHAN_CTRL, DMC_AXI1_G12_CHAN_CTRL,
			DMC_AXI2_G12_CHAN_CTRL, DMC_AXI3_G12_CHAN_CTRL,
			DMC_AXI4_G12_CHAN_CTRL, DMC_AXI5_G12_CHAN_CTRL,
			DMC_AXI6_G12_CHAN_CTRL, DMC_AXI7_G12_CHAN_CTRL,
			DMC_AXI8_G12_CHAN_CTRL, DMC_AXI9_G12_CHAN_CTRL,
			DMC_AXI10_G12_CHAN_CTRL, DMC_AXI1_G12_CHAN_CTRL,
			DMC_AXI12_G12_CHAN_CTRL, 0, 0, 0,
			DMC_AM0_G12_CHAN_CTRL, DMC_AM1_G12_CHAN_CTRL,
			DMC_AM2_G12_CHAN_CTRL, DMC_AM3_G12_CHAN_CTRL,
			DMC_AM4_G12_CHAN_CTRL, DMC_AM5_G12_CHAN_CTRL,
			DMC_AM6_G12_CHAN_CTRL, DMC_AM7_G12_CHAN_CTRL,};

		if (port >= 24 || port_reg[port] == 0)
			return;
		addr = port_reg[port];
	}

	/**
	 *bit 18. force this channel all request to be super urgent request.
	 *bit 17. force this channel all request to be urgent request.
	 *bit 16. force this channel all request to be non urgent request.
	 */
	val = readl(aml_db->ddr_reg1 + addr);
	val &= (~(0x7 << 16));
	val |= ((type & 0x7) << 16);
	writel(val, aml_db->ddr_reg1 + addr);
}
EXPORT_SYMBOL(dmc_set_urgent);

static ssize_t urgent_show(struct class *cla,
			   struct class_attribute *attr, char *buf)
{
	int i, s = 0;

	if (dual_dmc(aml_db) || quad_dmc(aml_db))
		return -EINVAL;

	if (!aml_db->real_ports || !aml_db->port_desc)
		return -EINVAL;

	s += sprintf(buf + s, "echo port val > /sys/class/aml_ddr/urgent\n"
			"val:\n\t1: non urgent;\n\t2: urgent;\n\t4: super urgent;\n"
			"port:   (hex integer)\n");
	for (i = 0; i < aml_db->real_ports; i++) {
		if (aml_db->port_desc[i].port_id >= 24)
			break;
		s += sprintf(buf + s, "\tbit%d: %s\n",
				aml_db->port_desc[i].port_id,
				aml_db->port_desc[i].port_name);
	}

	return s;
}

static ssize_t urgent_store(struct class *cla,
			    struct class_attribute *attr,
			    const char *buf, size_t count)
{
	unsigned int port = 0, val, i;

	if (sscanf(buf, "%x %d", &port, &val) != 2) {
		pr_info("invalid input:%s\n", buf);
		return -EINVAL;
	}
	for (i = 0; i < 24; i++) {
		if (port & 1)
			dmc_set_urgent(i, val);
		port >>= 1;
	}
	return count;
}
static CLASS_ATTR_RW(urgent);

#if DDR_BANDWIDTH_DEBUG
static ssize_t dump_reg_show(struct class *cla,
			     struct class_attribute *attr, char *buf)
{
	int s = 0;

	if (aml_db->ops && aml_db->ops->dump_reg)
		return aml_db->ops->dump_reg(aml_db, buf);

	return s;
}
static CLASS_ATTR_RO(dump_reg);
#endif

static ssize_t cpu_type_show(struct class *cla,
			     struct class_attribute *attr, char *buf)
{
	int cpu_type;

	cpu_type = aml_db->cpu_type;
	return sprintf(buf, "%x\n", cpu_type);
}
static CLASS_ATTR_RO(cpu_type);

static ssize_t name_of_ports_show(struct class *cla,
				  struct class_attribute *attr, char *buf)
{
	int i, s = 0;

	if (!aml_db->real_ports || !aml_db->port_desc)
		return -EINVAL;

	for (i = 0; i < aml_db->real_ports; i++) {
		s += sprintf(buf + s, "%2d, %s\n",
			     aml_db->port_desc[i].port_id,
			     aml_db->port_desc[i].port_name);
	}

	return s;
}
static CLASS_ATTR_RO(name_of_ports);

static ssize_t increase_tool_store(struct class *cla,
			    struct class_attribute *attr,
			    const char *buf, size_t count)
{
	long width_MB = 0;
	u64 min_width = 0;
	unsigned long t_s, t_e;
	u64 t_ns;
	u64 once_size;

	if (sscanf(buf, "%ld %lld", &width_MB, &t_ns) != 2) {
		if (kstrtoul(buf, 0, &width_MB)) {
			pr_info("invalid input:%s\n", buf);
			return -EINVAL;
		}
	} else {
		aml_db->increase_tool.t_ns = t_ns;
	}

	if (aml_db->increase_tool.t_ns == 0)
		aml_db->increase_tool.t_ns = 10000000; //default timer 10ms

	min_width = 1000000000;
	do_div(min_width, aml_db->increase_tool.t_ns);
	if (width_MB) {
		if (min_width > width_MB)
			pr_info("set width_MB too small, min:%lld\n", min_width);

		once_size = width_MB * 1024 * 1024;
		do_div(once_size, min_width);

		if (aml_db->increase_tool.increase_MB == 0) {
			aml_db->increase_tool.buf_addr = vmalloc(T_BUF_SIZE);
			if (IS_ERR(aml_db->increase_tool.buf_addr)) {
				pr_err("increase_tool vmalloc failed.\n");
				return count;
			}
		}

		t_s = sched_clock();
		memset(aml_db->increase_tool.buf_addr, 0x55, once_size);
		t_e = sched_clock();
		if ((t_e - t_s) > aml_db->increase_tool.t_ns) {
			pr_info("once copy time %lld than max %ld ns\n",
						aml_db->increase_tool.t_ns,
						t_e - t_s);
			return count;
		}
		pr_info("once copy time %ld ns, size %lld\n", t_e - t_s, once_size);
		aml_db->increase_tool.once_size = once_size;

		hrtimer_cancel(&ddr_hrtimer_timer);
		hrtimer_start(&ddr_hrtimer_timer,
						ktime_set(0, aml_db->increase_tool.t_ns),
						HRTIMER_MODE_REL);
	} else {
		hrtimer_cancel(&ddr_hrtimer_timer);
		aml_db->increase_tool.t_ns = 0;
		aml_db->increase_tool.once_size = 0;

		if (aml_db->increase_tool.increase_MB)
			vfree(aml_db->increase_tool.buf_addr);
	}

	aml_db->increase_tool.increase_MB = width_MB;
	pr_info("ddr will be increase %d MB/s, timer cycle:%lld ns\n",
						aml_db->increase_tool.increase_MB,
						aml_db->increase_tool.t_ns);
	return count;
}

static ssize_t increase_tool_show(struct class *cla,
			     struct class_attribute *attr, char *buf)
{
	return sprintf(buf, "current set:%d MB/s, timer cycle:%lld ns\n",
							aml_db->increase_tool.increase_MB,
							aml_db->increase_tool.t_ns);
}
static CLASS_ATTR_RW(increase_tool);

static struct attribute *aml_ddr_tool_attrs[] = {
	&class_attr_port.attr,
	&class_attr_irq_clock.attr,
	&class_attr_urgent.attr,
	&class_attr_threshold.attr,
	&class_attr_mode.attr,
	&class_attr_busy.attr,
	&class_attr_bandwidth.attr,
	&class_attr_freq.attr,
	&class_attr_cpu_type.attr,
	&class_attr_usage_stat.attr,
	&class_attr_name_of_ports.attr,
	&class_attr_increase_tool.attr,
#if DDR_BANDWIDTH_DEBUG
	&class_attr_dump_reg.attr,
#endif
	NULL
};
ATTRIBUTE_GROUPS(aml_ddr_tool);

static struct class aml_ddr_class = {
	.name = "aml_ddr",
	.class_groups = aml_ddr_tool_groups,
};

static int __init init_chip_config(int cpu, struct ddr_bandwidth *band)
{
	/* default init dmc_number is 1 */
	band->dmc_number = 1;

	switch (cpu) {
#ifdef CONFIG_AMLOGIC_DDR_BANDWIDTH_A1
	case DMC_TYPE_A1:
		band->ops = &a1_ddr_bw_ops;
		band->channels = 2;
		band->mali_port[0] = -1; /* no mali */
		band->mali_port[1] = -1;
		band->bytes_per_cycle = 8;
		break;
#endif
#ifdef CONFIG_AMLOGIC_DDR_BANDWIDTH_GX
	case DMC_TYPE_GXBB:
	case DMC_TYPE_GXTVBB:
		band->ops = &gx_ddr_bw_ops;
		band->channels = 1;
		band->mali_port[0] = 2;
		band->mali_port[1] = -1;
		break;
#endif
#ifdef CONFIG_AMLOGIC_DDR_BANDWIDTH_GXL
	case DMC_TYPE_GXL:
	case DMC_TYPE_GXM:
	case DMC_TYPE_TXL:
	case DMC_TYPE_TXLX:
	case DMC_TYPE_AXG:
	case DMC_TYPE_GXLX:
	case DMC_TYPE_TXHD:
		band->ops = &gxl_ddr_bw_ops;
		band->channels = 4;
		if (cpu == DMC_TYPE_AXG) {
			band->mali_port[0] = -1; /* no mali */
			band->mali_port[1] = -1;
		} else if (cpu == DMC_TYPE_GXM) {
			band->mali_port[0] = 1; /* port1: mali */
			band->mali_port[1] = -1;
		} else {
			band->mali_port[0] = 1; /* port1: mali0 */
			band->mali_port[1] = 2; /* port2: mali1 */
		}
		break;
#endif
#ifdef CONFIG_AMLOGIC_DDR_BANDWIDTH_G12
	case DMC_TYPE_G12A:
	case DMC_TYPE_G12B:
	case DMC_TYPE_SM1:
	case DMC_TYPE_TL1:
	case DMC_TYPE_TM2:
	case DMC_TYPE_C1:
	case DMC_TYPE_SC2:
		band->ops = &g12_ddr_bw_ops;
		band->channels = 4;
		if (cpu == DMC_TYPE_C1) {
			band->mali_port[0] = -1; /* no mali */
			band->mali_port[1] = -1;
		} else {
			band->mali_port[0] = 1; /* port1: mali */
			band->mali_port[1] = -1;
		}
		break;
#endif
#ifdef CONFIG_AMLOGIC_DDR_BANDWIDTH_T7
	case DMC_TYPE_T7:
	case DMC_TYPE_T3:
		band->ops            = &t7_ddr_bw_ops;
		band->channels     = 8;
		band->dmc_number   = 2;
		band->soc_feature |= DUAL_DMC;
		band->mali_port[0] = 3; /* port3: mali */
		band->mali_port[1] = 4;
		break;
	case DMC_TYPE_P1:
		band->ops            = &t7_ddr_bw_ops;
		band->channels     = 8;
		band->dmc_number   = 4;
		band->soc_feature |= QUAD_DMC;
		band->mali_port[0] = 3; /* port3: mali */
		band->mali_port[1] = 4;
		break;
#endif
#ifdef CONFIG_AMLOGIC_DDR_BANDWIDTH_T5
	case DMC_TYPE_T5:
	case DMC_TYPE_T5D:
		band->ops = &t5_ddr_bw_ops;
		aml_db->channels = 8;
		aml_db->mali_port[0] = 1; /* port1: mali */
		aml_db->mali_port[1] = -1;
		break;
#endif
#ifdef CONFIG_AMLOGIC_DDR_BANDWIDTH_S4
	case DMC_TYPE_S4:
	case DMC_TYPE_T5W:
		band->ops = &s4_ddr_bw_ops;
		aml_db->channels = 8;
		aml_db->mali_port[0] = 1; /* port1: mali */
		aml_db->mali_port[1] = -1;
		break;
#endif
	default:
		pr_err("%s, Can't find ops for chip:%x\n", __func__, cpu);
		return -1;
	}
	return 0;
}

static void get_ddr_external_bus_width(struct ddr_bandwidth *db,
				       unsigned long sec_base)
{
	unsigned long reg, base;

	if (db->cpu_type == DMC_TYPE_TM2)
		base = sec_base + (0x0100 << 2);
	else
		base = sec_base + (0x00da << 2);

	/* each axi cycle transfer 4 external bus */
	reg = dmc_rw(base, 0, DMC_READ);
	if (reg & BIT(16))	/* 16bit external bus width, 2 * 4 = 8*/
		db->bytes_per_cycle = 8;
	else			/* 32bit external bus width, 4 * 4 = 16 */
		db->bytes_per_cycle = 16;
	pr_info("bytes_per_cycle:%d, reg:%lx\n", db->bytes_per_cycle, reg);
}

/*
 * ddr_bandwidth_probe only executes before the init process starts
 * to run, so add __ref to indicate it is okay to call __init function
 * ddr_find_port_desc
 */
static int __init ddr_bandwidth_probe(struct platform_device *pdev)
{
	int r = 0;
#ifdef CONFIG_OF
	struct device_node *node = pdev->dev.of_node;
	/*struct pinctrl *p;*/
	struct resource *res;
	resource_size_t *base;
	unsigned int sec_base;
	int io_idx = 0;
#endif
	struct ddr_port_desc *desc = NULL;
	int pcnt;

	pr_info("%s, %d\n", __func__, __LINE__);
	aml_db = devm_kzalloc(&pdev->dev, sizeof(*aml_db), GFP_KERNEL);
	if (!aml_db)
		return -ENOMEM;

	aml_db->cpu_type = (unsigned long)of_device_get_match_data(&pdev->dev);
	pr_info("chip type:0x%x\n", aml_db->cpu_type);
	if (aml_db->cpu_type < DMC_TYPE_M8B) {
		pr_info("unsupport chip type:%d\n", aml_db->cpu_type);
		aml_db = NULL;
		return -EINVAL;
	}

	/* find and configure port description */
	pcnt = ddr_find_port_desc(aml_db->cpu_type, &desc);
	if (pcnt < 0) {
		pr_err("can't find port descriptor,cpu:%d\n", aml_db->cpu_type);
	} else {
		aml_db->port_desc = desc;
		aml_db->real_ports = pcnt;
	}

	if (init_chip_config(aml_db->cpu_type, aml_db)) {
		aml_db = NULL;
		return -EINVAL;
	}

#ifdef CONFIG_OF
	/* resource 0 for ddr register base */
	res = platform_get_resource(pdev, IORESOURCE_MEM, io_idx);
	if (res) {
		base = ioremap(res->start, res->end - res->start);
		aml_db->ddr_reg1 = (void *)base;
	} else {
		pr_err("can't get ddr reg base\n");
		aml_db = NULL;
		return -EINVAL;
	}
	io_idx++;

	if (dual_dmc(aml_db)) {
		/* next for ddr register base */
		res = platform_get_resource(pdev, IORESOURCE_MEM, io_idx);
		if (res) {
			base = ioremap(res->start, res->end - res->start);
			aml_db->ddr_reg2 = (void *)base;
			io_idx++;
		} else {
			pr_err("can't get ddr reg %d base\n", io_idx);
			aml_db = NULL;
			return -EINVAL;
		}
	}

	if (quad_dmc(aml_db)) {
		/* next for ddr register base */
		res = platform_get_resource(pdev, IORESOURCE_MEM, io_idx);
		if (res) {
			base = ioremap(res->start, res->end - res->start);
			aml_db->ddr_reg2 = (void *)base;
			io_idx++;
		} else {
			pr_err("can't get ddr reg %d base\n", io_idx);
			aml_db = NULL;
			return -EINVAL;
		}

		res = platform_get_resource(pdev, IORESOURCE_MEM, io_idx);
		if (res) {
			base = ioremap(res->start, res->end - res->start);
			aml_db->ddr_reg3 = (void *)base;
			io_idx++;
		} else {
			pr_err("can't get ddr reg %d base\n", io_idx);
			aml_db = NULL;
			return -EINVAL;
		}

		res = platform_get_resource(pdev, IORESOURCE_MEM, io_idx);
		if (res) {
			base = ioremap(res->start, res->end - res->start);
			aml_db->ddr_reg4 = (void *)base;
			io_idx++;
		} else {
			pr_err("can't get ddr reg %d base\n", io_idx);
			aml_db = NULL;
			return -EINVAL;
		}
	}

	/* next for pll register base */
	res = platform_get_resource(pdev, IORESOURCE_MEM, io_idx);
	if (res) {
		base = ioremap(res->start, res->end - res->start);
		aml_db->pll_reg = (void *)base;
	} else {
		pr_err("can't get ddr reg %d base\n", io_idx);
		aml_db = NULL;
		return -EINVAL;
	}

	aml_db->irq_num = of_irq_get(node, 0);
	r = of_property_read_u32(node, "sec_base", &sec_base);
	if (r < 0) {
		aml_db->bytes_per_cycle = 16;
		pr_info("can't find sec_base, set bytes_per_cycle to 16\n");
	} else {
		get_ddr_external_bus_width(aml_db, sec_base);
	}
#endif
	spin_lock_init(&aml_db->lock);
	aml_db->clock_count = DEFAULT_CLK_CNT;
	aml_db->mode = MODE_DISABLE;
	aml_db->threshold = DEFAULT_THRESHOLD * aml_db->bytes_per_cycle *
			    (aml_db->clock_count / 10000);

	if (!aml_db->ops->config_port)
		return -EINVAL;

	r = class_register(&aml_ddr_class);
	if (r)
		pr_info("%s, class regist failed\n", __func__);

	return 0;
}

static int ddr_bandwidth_remove(struct platform_device *pdev)
{
	if (aml_db) {
		class_destroy(&aml_ddr_class);
		free_irq(aml_db->irq_num, aml_db);
		kfree(aml_db->port_desc);
		iounmap(aml_db->ddr_reg1);
		iounmap(aml_db->pll_reg);
		aml_db = NULL;
	}

	return 0;
}

#ifdef CONFIG_OF
static const struct of_device_id aml_ddr_bandwidth_dt_match[] = {
#ifndef CONFIG_AMLOGIC_REMOVE_OLD
	{
		.compatible = "amlogic,ddr-bandwidth-m8b",
		.data = (void *)DMC_TYPE_M8B,	/* chip id */
	},
	{
		.compatible = "amlogic,ddr-bandwidth-gx",
		.data = (void *)DMC_TYPE_GXBB,
	},
	{
		.compatible = "amlogic,ddr-bandwidth-gxl",
		.data = (void *)DMC_TYPE_GXL,
	},
	{
		.compatible = "amlogic,ddr-bandwidth-gxm",
		.data = (void *)DMC_TYPE_GXM,
	},
	{
		.compatible = "amlogic,ddr-bandwidth-gxlx",
		.data = (void *)DMC_TYPE_GXLX,
	},
	{
		.compatible = "amlogic,ddr-bandwidth-axg",
		.data = (void *)DMC_TYPE_AXG,
	},
	{
		.compatible = "amlogic,ddr-bandwidth-txl",
		.data = (void *)DMC_TYPE_TXL,
	},
	{
		.compatible = "amlogic,ddr-bandwidth-txlx",
		.data = (void *)DMC_TYPE_TXLX,
	},
	{
		.compatible = "amlogic,ddr-bandwidth-txhd",
		.data = (void *)DMC_TYPE_TXHD,
	},
	{
		.compatible = "amlogic,ddr-bandwidth-tl1",
		.data = (void *)DMC_TYPE_TL1,
	},
	{
		.compatible = "amlogic,ddr-bandwidth-a1",
		.data = (void *)DMC_TYPE_A1,
	},
	{
		.compatible = "amlogic,ddr-bandwidth-c1",
		.data = (void *)DMC_TYPE_C1,
	},
#endif
	{
		.compatible = "amlogic,ddr-bandwidth-g12a",
		.data = (void *)DMC_TYPE_G12A,
	},
	{
		.compatible = "amlogic,ddr-bandwidth-g12b",
		.data = (void *)DMC_TYPE_G12B,
	},
	{
		.compatible = "amlogic,ddr-bandwidth-tm2",
		.data = (void *)DMC_TYPE_TM2,
	},
	{
		.compatible = "amlogic,ddr-bandwidth-t5",
		.data = (void *)DMC_TYPE_T5,
	},
	{
		.compatible = "amlogic,ddr-bandwidth-t5d",
		.data = (void *)DMC_TYPE_T5D,
	},
	{
		.compatible = "amlogic,ddr-bandwidth-t5w",
		.data = (void *)DMC_TYPE_T5W,
	},
	{
		.compatible = "amlogic,ddr-bandwidth-t7",
		.data = (void *)DMC_TYPE_T7,
	},
	{
		.compatible = "amlogic,ddr-bandwidth-t3",
		.data = (void *)DMC_TYPE_T3,
	},
	{
		.compatible = "amlogic,ddr-bandwidth-s4",
		.data = (void *)DMC_TYPE_S4,
	},
	{
		.compatible = "amlogic,ddr-bandwidth-sc2",
		.data = (void *)DMC_TYPE_SC2,
	},
	{
		.compatible = "amlogic,ddr-bandwidth-p1",
		.data = (void *)DMC_TYPE_P1,
	},
	{}
};
#endif

static struct platform_driver ddr_bandwidth_driver = {
	.driver = {
		.name = "amlogic,ddr-bandwidth",
		.owner = THIS_MODULE,
	},
	.remove = ddr_bandwidth_remove,
};

int __init ddr_bandwidth_init(void)
{
#ifdef CONFIG_OF
	const struct of_device_id *match_id;
	match_id = aml_ddr_bandwidth_dt_match;
	ddr_bandwidth_driver.driver.of_match_table = match_id;
#endif

	platform_driver_probe(&ddr_bandwidth_driver,
			      ddr_bandwidth_probe);

	ddr_hrtimer_init();
	return 0;
}

void ddr_bandwidth_exit(void)
{
	platform_driver_unregister(&ddr_bandwidth_driver);
	ddr_hrtimer_cancel();
}

