// SPDX-License-Identifier: GPL-2.0
/*
 * Renesas RCar Gen2 USB PHY driver
 *
 * Copyright (C) 2018 Marek Vasut <marek.vasut@gmail.com>
 */

#include <clk.h>
#include <div64.h>
#include <dm.h>
#include <fdtdec.h>
#include <generic-phy.h>
#include <malloc.h>
#include <reset.h>
#include <syscon.h>
#include <usb.h>
#include <asm/io.h>
#include <dm/device_compat.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <power/regulator.h>

#define USBHS_LPSTS			0x02
#define USBHS_UGCTRL			0x80
#define USBHS_UGCTRL2			0x84
#define USBHS_UGSTS			0x88	/* From technical update */

/* Low Power Status register (LPSTS) */
#define USBHS_LPSTS_SUSPM		0x4000

/* USB General control register (UGCTRL) */
#define USBHS_UGCTRL_CONNECT		BIT(2)
#define USBHS_UGCTRL_PLLRESET		BIT(0)

/* USB General control register 2 (UGCTRL2) */
#define USBHS_UGCTRL2_USB2SEL		0x80000000
#define USBHS_UGCTRL2_USB2SEL_PCI	0x00000000
#define USBHS_UGCTRL2_USB2SEL_USB30	0x80000000
#define USBHS_UGCTRL2_USB0SEL		0x00000030
#define USBHS_UGCTRL2_USB0SEL_PCI	0x00000010
#define USBHS_UGCTRL2_USB0SEL_HS_USB	0x00000030

/* USB General status register (UGSTS) */
#define USBHS_UGSTS_LOCK		0x00000100 /* From technical update */

#define PHYS_PER_CHANNEL	2

struct rcar_gen2_phy {
	fdt_addr_t	regs;
	struct clk	clk;
};

static int rcar_gen2_phy_phy_init(struct phy *phy)
{
	struct rcar_gen2_phy *priv = dev_get_priv(phy->dev);
	u16 chan = phy->id & 0xffff;
	u16 mode = (phy->id >> 16) & 0xffff;
	u32 clrmask, setmask;

	if (chan == 0) {
		clrmask = USBHS_UGCTRL2_USB0SEL;
		setmask = mode ? USBHS_UGCTRL2_USB0SEL_HS_USB :
				 USBHS_UGCTRL2_USB0SEL_PCI;
	} else {
		clrmask = USBHS_UGCTRL2_USB2SEL;
		setmask = mode ? USBHS_UGCTRL2_USB2SEL_USB30 :
				 USBHS_UGCTRL2_USB2SEL_PCI;
	}
	clrsetbits_le32(priv->regs + USBHS_UGCTRL2, clrmask, setmask);

	return 0;
}

static int rcar_gen2_phy_phy_power_on(struct phy *phy)
{
	struct rcar_gen2_phy *priv = dev_get_priv(phy->dev);
	int i;
	u32 value;

	/* Power on USBHS PHY */
	clrbits_le32(priv->regs + USBHS_UGCTRL, USBHS_UGCTRL_PLLRESET);

	setbits_le16(priv->regs + USBHS_LPSTS, USBHS_LPSTS_SUSPM);

	for (i = 0; i < 20; i++) {
		value = readl(priv->regs + USBHS_UGSTS);
		if ((value & USBHS_UGSTS_LOCK) == USBHS_UGSTS_LOCK) {
			setbits_le32(priv->regs + USBHS_UGCTRL,
				     USBHS_UGCTRL_CONNECT);
			return 0;
		}
		udelay(1);
	}

	return -ETIMEDOUT;
}

static int rcar_gen2_phy_phy_power_off(struct phy *phy)
{
	struct rcar_gen2_phy *priv = dev_get_priv(phy->dev);

	/* Power off USBHS PHY */
	clrbits_le32(priv->regs + USBHS_UGCTRL, USBHS_UGCTRL_CONNECT);

	clrbits_le16(priv->regs + USBHS_LPSTS, USBHS_LPSTS_SUSPM);

	setbits_le32(priv->regs + USBHS_UGCTRL, USBHS_UGCTRL_PLLRESET);

	return 0;
}

static int rcar_gen2_phy_of_xlate(struct phy *phy,
				  struct ofnode_phandle_args *args)
{
	if (args->args_count != 2) {
		dev_err(phy->dev, "Invalid DT PHY argument count: %d\n",
			args->args_count);
		return -EINVAL;
	}

	if (args->args[0] != 0 && args->args[0] != 2) {
		dev_err(phy->dev, "Invalid DT PHY channel: %d\n",
			args->args[0]);
		return -EINVAL;
	}

	if (args->args[1] != 0 && args->args[1] != 1) {
		dev_err(phy->dev, "Invalid DT PHY mode: %d\n",
			args->args[1]);
		return -EINVAL;
	}

	if (args->args_count)
		phy->id = args->args[0] | (args->args[1] << 16);
	else
		phy->id = 0;

	return 0;
}

static const struct phy_ops rcar_gen2_phy_phy_ops = {
	.init		= rcar_gen2_phy_phy_init,
	.power_on	= rcar_gen2_phy_phy_power_on,
	.power_off	= rcar_gen2_phy_phy_power_off,
	.of_xlate	= rcar_gen2_phy_of_xlate,
};

static int rcar_gen2_phy_probe(struct udevice *dev)
{
	struct rcar_gen2_phy *priv = dev_get_priv(dev);
	int ret;

	priv->regs = dev_read_addr(dev);
	if (priv->regs == FDT_ADDR_T_NONE)
		return -EINVAL;

	/* Enable clock */
	ret = clk_get_by_index(dev, 0, &priv->clk);
	if (ret)
		return ret;

	ret = clk_enable(&priv->clk);
	if (ret)
		return ret;

	return 0;
}

static int rcar_gen2_phy_remove(struct udevice *dev)
{
	struct rcar_gen2_phy *priv = dev_get_priv(dev);

	clk_disable(&priv->clk);

	return 0;
}

static const struct udevice_id rcar_gen2_phy_of_match[] = {
	{ .compatible = "renesas,rcar-gen2-usb-phy", },
	{ },
};

U_BOOT_DRIVER(rcar_gen2_phy) = {
	.name		= "rcar-gen2-phy",
	.id		= UCLASS_PHY,
	.of_match	= rcar_gen2_phy_of_match,
	.ops		= &rcar_gen2_phy_phy_ops,
	.probe		= rcar_gen2_phy_probe,
	.remove		= rcar_gen2_phy_remove,
	.priv_auto	= sizeof(struct rcar_gen2_phy),
};
