// SPDX-License-Identifier: GPL-2.0
/*
 * xHCI host controller toolkit driver for vrt vref
 *
 * 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_USB20_VRT_VREF_SEL_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_USB20_VRT_VREF_SEL usage:\n");
	cnt += sprintf(buf + cnt,
		"   echo u2p index 3b011 > RG_USB20_VRT_VREF_SEL\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 3b101 > RG_USB20_VRT_VREF_SEL\n");
	cnt += sprintf(buf + cnt,
		"  port2 binding phy 0, tune 3b'010 as VRT_VREF value\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_USB20_VRT_VREF_SEL_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_USB20_VRT_VREF_SEL(%lu): %s\n", n, buf);

	words = sscanf(buf, "%i %i 3b%3[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_USBPHYACR1;

	addr = ioremap_nocache(io, 4);
	val = binary_write_width3(addr, SHFT_RG_USB20_VRT_VREF_SEL, 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_USB20_VRT_VREF_SEL);
