/*
 * Samsung EXYNOS SoC series USB DRD PHY DebugFS file
 *
 * Phy provider for USB 3.0 DRD controller on Exynos SoC series
 *
 * Copyright (C) 2016 Samsung Electronics Co., Ltd.
 * Author: Kyounghye Yun <k-hye.yun@samsung.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/ptrace.h>
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/delay.h>
#include <linux/uaccess.h>
#include <linux/device.h>
#include <linux/regmap.h>

#include <linux/usb/ch9.h>
#include "phy-exynos-usbdrd.h"
#include "phy-exynos-usbdp-reg.h"
#include "phy-exynos-debug.h"

static struct exynos_debugfs_prvdata *prvdata_dp;

/* PHY Combo DP register set */
static const struct debugfs_reg32 exynos_usb3drd_dp_regs[] = {
	dump_register_dp(TRSV_R01),
	dump_register_dp(TRSV_R02),
	dump_register_dp(TRSV_R03),
	dump_register_dp(TRSV_R04),
	dump_register_dp(TRSV_R0C),
};

/* PHY Combo DP register set */
static const struct debugfs_regmap32 exynos_usb3drd_dp_regmap[] = {
	dump_regmap_dp_mask(TRSV_R01, USBDP_TRSV01, RXAFE_LEQ_ISEL_GEN2, 6),
	dump_regmap_dp_mask(TRSV_R01, USBDP_TRSV01, RXAFE_LEQ_ISEL_GEN1, 4),
	dump_regmap_dp_mask(TRSV_R01, USBDP_TRSV01, RXAFE_CTLE_SEL, 2),
	dump_regmap_dp_mask(TRSV_R01, USBDP_TRSV01, RXAFE_SCLBUF_EN, 0),
	dump_regmap_dp_mask(TRSV_R02, USBDP_TRSV02, RXAFE_LEQ_CSEL_GEN2, 4),
	dump_regmap_dp_mask(TRSV_R02, USBDP_TRSV02, RXAFE_LEQ_CSEL_GEN1, 0),
	dump_regmap_dp_mask(TRSV_R03, USBDP_TRSV03, RXAFE_LEQ_RSEL_GEN2, 3),
	dump_regmap_dp_mask(TRSV_R03, USBDP_TRSV03, RXAFE_LEQ_RSEL_GEN1, 0),
	dump_regmap_dp_mask(TRSV_R04, USBDP_TRSV04, RXAFE_SQ_VFFSET_CTRL, 0),
	dump_regmap_dp_mask(TRSV_R0C, USBDP_TRSV0C, MAN_TX_DE_EMP_LVL, 4),
	dump_regmap_dp_mask(TRSV_R0C, USBDP_TRSV0C, MAN_TX_DRVR_LVL, 0),
};

static int debugfs_phy_power_state(struct exynos_usbdrd_phy *phy_drd, int phy_index)
{
	struct regmap *reg_pmu;
	u32 pmu_offset;
	int phy_on;
	int ret;

	reg_pmu = phy_drd->phys[phy_index].reg_pmu;
	pmu_offset = phy_drd->phys[phy_index].pmu_offset;
	ret = regmap_read(reg_pmu, pmu_offset, &phy_on);
	if (ret) {
		dev_err(phy_drd->dev, "Can't read 0x%x\n", pmu_offset);
		return ret;
	}
	phy_on &= phy_drd->phys[phy_index].pmu_mask;

	return phy_on;
}

static int debugfs_print_regmap(struct seq_file *s, const struct debugfs_regmap32 *regs,
				int nregs, void __iomem *base,
				const struct debugfs_reg32 *parent)
{
	int i, j = 0;
	int bit = 0;
	unsigned int bitmask;
	int max_string = 24;
	int calc_tab;
	u32 bit_value, reg_value;

	reg_value = readl(base + parent->offset);
	seq_printf(s, "%s (0x%04lx) : 0x%08x\n", parent->name,
							parent->offset, reg_value);
	for (i = 0; i < nregs; i++, regs++) {
		if (!strcmp(regs->name, parent->name)) {
			bit_value = (reg_value & regs->bitmask) >> regs->bitoffset;

			seq_printf(s, "\t%s", regs->bitname);
			calc_tab = max_string/8 - strlen(regs->bitname)/8;
			for (j = 0 ; j < calc_tab; j++)
				seq_puts(s, "\t");

			if (regs->mask) {
				bitmask = regs->bitmask;
				bitmask = bitmask >> regs->bitoffset;
				while (bitmask) {
					bitmask = bitmask >> 1;
					bit++;
				}
				seq_printf(s, "[%d:%d]\t: 0x%x\n", (int)regs->bitoffset,
						((int)regs->bitoffset + bit - 1), bit_value);
				bit = 0;
			} else {
				seq_printf(s, "[%d]\t: 0x%x\n", (int)regs->bitoffset,
										bit_value);
			}
		}
	}
	return 0;

}

static int debugfs_show_regmap(struct seq_file *s, void *data)
{
	struct exynos_debugfs_prvdata *prvdata = s->private;
	struct debugfs_regset_map *regmap = prvdata->regmap;
	struct debugfs_regset32 *regset = prvdata->regset;
	const struct debugfs_reg32 *regs = regset->regs;
	int phy_on, i = 0;

	phy_on = debugfs_phy_power_state(prvdata->phy_drd, 0);
	if (phy_on < 0) {
		seq_printf(s, "can't read PHY register, error : %d\n", phy_on);
		return -EIO;
	}
	if (!phy_on) {
		seq_puts(s, "can't get PHY register, PHY: Power OFF\n");
		return 0;
	}
	for (i = 0; i < regset->nregs; i++, regs++) {
		debugfs_print_regmap(s, regmap->regs, regmap->nregs,
						regset->base, regs);
	}

	return 0;
}

static int debugfs_open_regmap(struct inode *inode, struct file *file)
{
	return single_open(file, debugfs_show_regmap, inode->i_private);
}

static const struct file_operations fops_regmap = {
	.open =		debugfs_open_regmap,
	.read =		seq_read,
	.llseek =	seq_lseek,
	.release =	single_release,
};

static int debugfs_print_regdump(struct seq_file *s, struct exynos_usbdrd_phy *phy_drd,
				const struct debugfs_reg32 *regs, int nregs,
				void __iomem *base)
{
	int phy_on;
	int i;

	for (i = 0; i < EXYNOS_DRDPHYS_NUM; i++) {
		phy_on = debugfs_phy_power_state(phy_drd, i);
		if (phy_on < 0) {
			seq_printf(s, "can't read PHY register, error : %d\n", phy_on);
			return phy_on;
		}
		if (!phy_on) {
			seq_printf(s, "can't get PHY register, PHY%d : Power OFF\n", i);
			continue;
		}

		for (i = 0; i < nregs; i++, regs++) {
			seq_printf(s, "%s", regs->name);
			if (strlen(regs->name) < 8)
				seq_puts(s, "\t\t");
			else
				seq_puts(s, "\t");

			seq_printf(s, "= 0x%08x\n", readl(base + regs->offset));
		}
	}

	return 0;
}
static int debugfs_show_regdump(struct seq_file *s, void *data)
{
	struct exynos_debugfs_prvdata *prvdata = s->private;
	struct debugfs_regset32 *regset = prvdata->regset;
	int ret;

	ret = debugfs_print_regdump(s, prvdata->phy_drd, regset->regs,
					regset->nregs, regset->base);
	if (ret < 0)
		return ret;

	return 0;
}

static int debugfs_open_regdump(struct inode *inode, struct file *file)
{
	return single_open(file, debugfs_show_regdump, inode->i_private);
}

static const struct file_operations fops_regdump = {
	.open =		debugfs_open_regdump,
	.read =		seq_read,
	.llseek =	seq_lseek,
	.release =	single_release,
};
static int debugfs_show_bitset(struct seq_file *s, void *data)
{
	char *b_name = s->private;
	struct debugfs_regset_map *regmap = prvdata_dp->regmap;
	const struct debugfs_regmap32 *cmp = regmap->regs;
	const struct debugfs_regmap32 *regs;
	unsigned int bitmask;
	int i, bit = 0;
	u32 reg_value, bit_value;
	u32 detect_regs = 0;

	for (i = 0; i < regmap->nregs; i++, cmp++) {
		if (!strcmp(cmp->bitname, b_name)) {
			regs = cmp;
			detect_regs = 1;
			break;
		}
	}

	if (!detect_regs)
		return -EINVAL;

	reg_value = readl(prvdata_dp->regset->base + regs->offset);
	bit_value = (reg_value & regs->bitmask) >> regs->bitoffset;
	if (regs->mask) {
		bitmask = regs->bitmask;
		bitmask = bitmask >> regs->bitoffset;
		while (bitmask) {
			bitmask = bitmask >> 1;
			bit++;
		}
		seq_printf(s, "%s [%d:%d] = 0x%x\n", regs->name,
				(int)regs->bitoffset,
				((int)regs->bitoffset + bit - 1), bit_value);
	} else {
		seq_printf(s, "%s [%d] = 0x%x\n", regs->name,
				(int)regs->bitoffset, bit_value);
	}
	return 0;
}
static ssize_t debugfs_write_regset(struct file *file,
		const char __user *ubuf, size_t count, loff_t *ppos)
{
	struct seq_file *s = file->private_data;
	char *reg_name = s->private;
	struct debugfs_regset32 *regset = prvdata_dp->regset;
	const struct debugfs_reg32 *regs = regset->regs;
	unsigned long value;
	char buf[8];
	int i;

	if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
		return -EFAULT;

	value = simple_strtol(buf, NULL, 16);

	for (i = 0; i < regset->nregs; i++, regs++) {
		if (!strcmp(regs->name, reg_name))
			break;
	}

	writel(value, regset->base + regs->offset);

	return count;
}
static ssize_t debugfs_write_bitset(struct file *file,
		const char __user *ubuf, size_t count, loff_t *ppos)
{
	struct seq_file *s = file->private_data;
	char *b_name = s->private;
	struct debugfs_regset_map *regmap = prvdata_dp->regmap;
	const struct debugfs_regmap32 *regs = regmap->regs;
	unsigned long value;
	char buf[32];
	int i;
	u32 reg_value;

	if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) {
		seq_printf(s, "%s, write error\n", __func__);
		return -EFAULT;
	}
	value = simple_strtol(buf, NULL, 2);

	for (i = 0; i < regmap->nregs; i++, regs++) {
		if (!strcmp(regs->bitname, b_name))
			break;
	}

	value = value << regs->bitoffset;
	reg_value = readl(prvdata_dp->regset->base + regs->offset);
	reg_value &= ~(regs->bitmask);
	reg_value |= (u32)value;
	writel(reg_value, prvdata_dp->regset->base + regs->offset);

	return count;
}

static int debugfs_open_bitset(struct inode *inode, struct file *file)
{
	return single_open(file, debugfs_show_bitset, inode->i_private);
}

static int debugfs_show_regset(struct seq_file *s, void *data)
{
	char *p_name = s->private;
	struct debugfs_regset32 *regset = prvdata_dp->regset;
	struct debugfs_regset_map *regmap = prvdata_dp->regmap;
	const struct debugfs_reg32 *regs = regset->regs;
	const struct debugfs_reg32 *parents;
	u32 detect_regs = 0;


	int i;

	for (i = 0; i < regset->nregs; i++, regs++) {
		if (!strcmp(regs->name, p_name)) {
			parents = regs;
			detect_regs = 1;
			break;
		}
	}
	if (!detect_regs)
		return -EINVAL;

	debugfs_print_regmap(s, prvdata_dp->regmap->regs, regmap->nregs,
						regset->base, parents);

	return 0;
}

static int debugfs_open_regset(struct inode *inode, struct file *file)
{
	return single_open(file, debugfs_show_regset, inode->i_private);
}

static const struct file_operations fops_regset = {
	.open =		debugfs_open_regset,
	.write =	debugfs_write_regset,
	.read =		seq_read,
	.llseek =	seq_lseek,
	.release =	single_release,
};

static const struct file_operations fops_bitset = {
	.open =		debugfs_open_bitset,
	.write =	debugfs_write_bitset,
	.read =		seq_read,
	.llseek =	seq_lseek,
	.release =	single_release,
};

static int debugfs_create_regfile(struct exynos_debugfs_prvdata *prvdata,
					const struct debugfs_reg32 *parents,
					struct dentry *root)
{
	struct debugfs_regset_map *regmap = prvdata->regmap;
	const struct debugfs_regmap32 *regs = regmap->regs;
	struct dentry *file;
	int i, ret;

	file = debugfs_create_file(parents->name, 0644, root,
							parents->name, &fops_regset);
	if (!file) {
		ret = -ENOMEM;
		return ret;
	}
	for (i = 0; i < regmap->nregs; i++, regs++) {
		if (!strcmp(regs->name, parents->name)) {
			file = debugfs_create_file(regs->bitname, 0644,
					root, regs->bitname, &fops_bitset);
			if (!file) {
				ret = -ENOMEM;
				return ret;
			}
		}
	}

	return 0;
}

static int debugfs_create_regdir(struct exynos_debugfs_prvdata *prvdata,
						struct dentry *root)
{
	struct exynos_usbdrd_phy *phy_drd = prvdata->phy_drd;
	struct debugfs_regset32 *regset = prvdata->regset;
	const struct debugfs_reg32 *regs = regset->regs;
	struct dentry	*dir;
	int ret, i;

	for (i = 0; i < regset->nregs; i++, regs++) {
		dir = debugfs_create_dir(regs->name, root);
		if (!dir) {
			dev_err(phy_drd->dev, "failed to create '%s' reg dir",
								regs->name);
			return -ENOMEM;
		}
		ret = debugfs_create_regfile(prvdata, regs, dir);
		if (ret < 0) {
			dev_err(phy_drd->dev, "failed to create bitfile for %s, error : %d\n",
						regs->name, ret);
			return ret;
		}
	}

	return 0;
}
int exynos_usbdrd_dp_debugfs_init(struct exynos_usbdrd_phy *phy_drd)
{
	struct device	*dev = phy_drd->dev;
	struct dentry	*root;
	struct dentry	*dir;
	struct dentry	*file;
	u32 version = phy_drd->usbphy_sub_info.version;
	int		ret;

	root = debugfs_create_dir("110a0000.usbdp", NULL);
	if (!root) {
		dev_err(dev, "failed to create root directory for USBPHY debugfs");
		ret = -ENOMEM;
		goto err0;
	}

	prvdata_dp = devm_kmalloc(dev, sizeof(struct exynos_debugfs_prvdata), GFP_KERNEL);
	if (!prvdata_dp) {
		dev_err(dev, "failed to alloc private data for debugfs");
		ret = -ENOMEM;
		goto err1;
	}
	prvdata_dp->root = root;
	prvdata_dp->phy_drd = phy_drd;

	prvdata_dp->regset = devm_kmalloc(dev, sizeof(*prvdata_dp->regset), GFP_KERNEL);
	if (!prvdata_dp->regset) {
		dev_err(dev, "failed to alloc regmap");
		ret = -ENOMEM;
		goto err1;
	}

	if (phy_drd->usbphy_sub_info.version == EXYNOS_USBCON_VER_04_0_0) {
		/* for USB3PHY Lhotse */
		prvdata_dp->regset->regs = exynos_usb3drd_dp_regs;
		prvdata_dp->regset->nregs = ARRAY_SIZE(exynos_usb3drd_dp_regs);
	}

	prvdata_dp->regset->base = phy_drd->reg_phy2;

	prvdata_dp->regmap = devm_kmalloc(dev, sizeof(*prvdata_dp->regmap), GFP_KERNEL);
	if (!prvdata_dp->regmap) {
		dev_err(dev, "failed to alloc regmap");
		ret = -ENOMEM;
		goto err1;
	}

	if (version == EXYNOS_USBCON_VER_04_0_0) {
		/* for USB3PHY Lhotse */
		prvdata_dp->regmap->regs = exynos_usb3drd_dp_regmap;
		prvdata_dp->regmap->nregs = ARRAY_SIZE(exynos_usb3drd_dp_regmap);
	}

	file = debugfs_create_file("regdump", 0444, root, prvdata_dp, &fops_regdump);
	if (!file) {
		dev_err(dev, "failed to create file for register dump");
		ret = -ENOMEM;
		goto err1;
	}

	file = debugfs_create_file("regmap", 0444, root, prvdata_dp, &fops_regmap);
	if (!file) {
		dev_err(dev, "failed to create file for register dump");
		ret = -ENOMEM;
		goto err1;
	}

	dir = debugfs_create_dir("regset", root);
	if (!dir) {
		ret = -ENOMEM;
		goto err1;
	}

	ret = debugfs_create_regdir(prvdata_dp, dir);
	if (ret < 0) {
		dev_err(dev, "failed to create regfile, error = %d\n", ret);
		goto err1;
	}


	return 0;

err1:
	debugfs_remove_recursive(root);
err0:
	return ret;
}
