// SPDX-License-Identifier: GPL-2.0
/*
 * xHCI host controller toolkit driver for chgdt-en
 *
 * Copyright (C) 2021  MediaTek Inc.
 *
 *  Author: Zhanyong Wang <zhanyong.wang@mediatek.com>
 */

#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/usb.h>
#include "xhci-mtk.h"
#include "xhci-mtk-test.h"
#include "xhci-mtk-unusual.h"

static ssize_t RG_CHGDT_EN_show(struct device *dev,
			struct device_attribute *attr, char *buf)
{
	struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev);
	struct usb_hcd *hcd = mtk->hcd;
	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
	ssize_t cnt = 0;
	void __iomem *addr;
	u32 val;
	u32 i;
	int ports;
	char str[32];
	int index = 0;
	u32 io, length;
	int ret;

	ports = mtk->num_u3_ports + mtk->num_u2_ports;
	cnt += sprintf(buf + cnt, " RG_CHGDT_EN usage:\n");
	cnt += sprintf(buf + cnt,
		"   echo u2p index 1b0 > RG_CHGDT_EN\n");
	if (mtk->num_u3_ports + 1 != ports)
		cnt += sprintf(buf + cnt, "	parameter: u2p: %i ~ %i\n",
					mtk->num_u3_ports + 1, ports);
	else
		cnt += sprintf(buf + cnt, "	parameter: u2p: %i\n",
					mtk->num_u3_ports + 1);
	if (mtk->num_u2_ports > 1)
		cnt += sprintf(buf + cnt, "	parameter: index: 0 ~ %i\n",
			       mtk->num_u2_ports);
	else
		cnt += sprintf(buf + cnt, "	parameter: index: 0\n");

	cnt += sprintf(buf + cnt, " e.g.: echo 2 0 1b1 > RG_CHGDT_EN\n");
	cnt += sprintf(buf + cnt,
		"  port2 binding phy 0, enable 1b'1 as CHGDT_EN\n");

	cnt += sprintf(buf + cnt,
			"\n=========current HQA setting check=========\n");
	for (i = 1; i <= ports; i++) {
		addr = &xhci->op_regs->port_status_base +
			NUM_PORT_REGS * ((i - 1) & 0xff);
		val = readl(addr);
		if (i <= mtk->num_u3_ports) {
			cnt += sprintf(buf + cnt,
				       "USB30 Port%i: 0x%08X\n", i, val);
		} else {
			cnt += sprintf(buf + cnt,
				       "USB20 Port%i: 0x%08X\n", i, val);

			ret = query_phy_addr(dev->of_node,
						 &index, &io, &length);
			if (ret && ret != -EACCES) {
				if (ret == -EPERM)
					cnt += sprintf(buf + cnt,
					"USB20 Port%i (Phy%i: absent)\n",
					i, index);
				else
					cnt += sprintf(buf + cnt,
					"USB20 Port%i (Phy%i) failure %i\n",
						 i, index, ret);
				continue;
			}

			cnt += sprintf(buf + cnt,
				"USB20 Port%i (Phy%i:%sable): 0x%08X 0x%08X\n",
				i, index, ret ? " dis" : " en", io, length);

			addr   = ioremap_nocache(io, length);
			addr  += (length != 0x100) ? 0x300 : 0;

			HQA_INFORMACTION_COLLECTS();

			iounmap(addr);
			index ++;
		}
	}

	if (mtk->hqa_pos) {
		cnt += sprintf(buf + cnt, "%s", mtk->hqa_buf);
		mtk->hqa_pos = 0;
	}

	return cnt;
}

static ssize_t RG_CHGDT_EN_store(struct device *dev,
                        struct device_attribute *attr,
                        const char *buf, size_t n)
{
	u32 val;
	u32 io;
	u32 length;
	int ports;
	int words;
	int port;
	int index;
	int ret;
	char *str = NULL;
	void __iomem *addr;
	struct xhci_hcd_mtk *mtk  = dev_get_drvdata(dev);
	struct device_node  *node = dev->of_node;

	ports = mtk->num_u3_ports + mtk->num_u2_ports;
	mtk->hqa_pos = 0;

	memset(mtk->hqa_buf, 0, mtk->hqa_size);

	str = kzalloc(n, GFP_ATOMIC);

	hqa_info(mtk, "RG_CHGDT_EN(%lu): %s\n", n, buf);

	words = sscanf(buf, "%i %i 1b%1[0,1]", &port, &index, str);
	if ((words != 3) ||
	    (port < mtk->num_u3_ports || port > ports)) {
		hqa_info(mtk, "Check params(%i):\" %i %i %s\", Please!\n",
			words, port, index, str);

		ret = -EINVAL;
		goto error;
	}

	hqa_info(mtk, " params: %i %i %s\n",
		port, index, str);

	ret = query_phy_addr(node, &index, &io, &length);
	if (ret && ret != -EACCES)
		goto error;

	io += (length != 0x100) ? 0x300 : 0;
	io += USB20_PHY_U2PHYBC12C;

	addr = ioremap_nocache(io, 4);
	val = binary_write_width1(addr, SHFT_RG_CHGDT_EN, str);
	hqa_info(mtk, "Port%i(Phy%i)[0x%08X]: 0x%08X but 0x%08X\n",
		port, index, io, val, readl(addr));

	iounmap(addr);
	ret = n;

error:
	kfree(str);
	return ret;
}
DEVICE_ATTR_RW(RG_CHGDT_EN);
