// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2022 Sumit Garg <sumit.garg@linaro.org>
 *
 * Based on Linux driver
 */

#include <dm.h>
#include <generic-phy.h>
#include <reset.h>
#include <clk.h>
#include <asm/io.h>
#include <linux/delay.h>

/* PHY register and bit definitions */
#define PHY_CTRL_COMMON0		0x078
#define SIDDQ				BIT(2)

struct hsphy_init_seq {
	int offset;
	int val;
	int delay;
};

struct hsphy_data {
	const struct hsphy_init_seq *init_seq;
	unsigned int init_seq_num;
};

struct hsphy_priv {
	void __iomem *base;
	struct clk_bulk clks;
	struct reset_ctl phy_rst;
	struct reset_ctl por_rst;
	const struct hsphy_data *data;
};

static int hsphy_power_on(struct phy *phy)
{
	struct hsphy_priv *priv = dev_get_priv(phy->dev);
	u32 val;

	val = readb(priv->base + PHY_CTRL_COMMON0);
	val &= ~SIDDQ;
	writeb(val, priv->base + PHY_CTRL_COMMON0);

	return 0;
}

static int hsphy_power_off(struct phy *phy)
{
	struct hsphy_priv *priv = dev_get_priv(phy->dev);
	u32 val;

	val = readb(priv->base + PHY_CTRL_COMMON0);
	val |= SIDDQ;
	writeb(val, priv->base + PHY_CTRL_COMMON0);

	return 0;
}

static int hsphy_reset(struct hsphy_priv *priv)
{
	int ret;

	ret = reset_assert(&priv->phy_rst);
	if (ret)
		return ret;

	udelay(10);

	ret = reset_deassert(&priv->phy_rst);
	if (ret)
		return ret;

	udelay(80);

	return 0;
}

static void hsphy_init_sequence(struct hsphy_priv *priv)
{
	const struct hsphy_data *data = priv->data;
	const struct hsphy_init_seq *seq;
	int i;

	/* Device match data is optional. */
	if (!data)
		return;

	seq = data->init_seq;

	for (i = 0; i < data->init_seq_num; i++, seq++) {
		writeb(seq->val, priv->base + seq->offset);
		if (seq->delay)
			udelay(seq->delay);
	}
}

static int hsphy_por_reset(struct hsphy_priv *priv)
{
	int ret;
	u32 val;

	ret = reset_assert(&priv->por_rst);
	if (ret)
		return ret;

	/*
	 * The Femto PHY is POR reset in the following scenarios.
	 *
	 * 1. After overriding the parameter registers.
	 * 2. Low power mode exit from PHY retention.
	 *
	 * Ensure that SIDDQ is cleared before bringing the PHY
	 * out of reset.
	 */
	val = readb(priv->base + PHY_CTRL_COMMON0);
	val &= ~SIDDQ;
	writeb(val, priv->base + PHY_CTRL_COMMON0);

	/*
	 * As per databook, 10 usec delay is required between
	 * PHY POR assert and de-assert.
	 */
	udelay(10);
	ret = reset_deassert(&priv->por_rst);
	if (ret)
		return ret;

	/*
	 * As per databook, it takes 75 usec for PHY to stabilize
	 * after the reset.
	 */
	udelay(80);

	return 0;
}

static int hsphy_clk_init(struct udevice *dev, struct hsphy_priv *priv)
{
	int ret;

	ret = clk_get_bulk(dev, &priv->clks);
	if (ret == -ENOSYS || ret == -ENOENT)
		return 0;
	if (ret)
		return ret;

	ret = clk_enable_bulk(&priv->clks);
	if (ret) {
		clk_release_bulk(&priv->clks);
		return ret;
	}

	return 0;
}

static int hsphy_init(struct phy *phy)
{
	struct hsphy_priv *priv = dev_get_priv(phy->dev);
	int ret;

	ret = hsphy_clk_init(phy->dev, priv);
	if (ret)
		return ret;

	ret = hsphy_reset(priv);
	if (ret)
		return ret;

	hsphy_init_sequence(priv);

	hsphy_por_reset(priv);
	if (ret)
		return ret;

	return 0;
}

static int hsphy_probe(struct udevice *dev)
{
	struct hsphy_priv *priv = dev_get_priv(dev);
	int ret;

	priv->base = dev_read_addr_ptr(dev);
	if (!priv->base)
		return -EINVAL;

	ret = reset_get_by_name(dev, "phy", &priv->phy_rst);
	if (ret)
		return ret;

	ret = reset_get_by_name(dev, "por", &priv->por_rst);
	if (ret)
		return ret;

	priv->data = (const struct hsphy_data *)dev_get_driver_data(dev);

	return 0;
}

static struct phy_ops hsphy_ops = {
	.power_on = hsphy_power_on,
	.power_off = hsphy_power_off,
	.init = hsphy_init,
};

/*
 * The macro is used to define an initialization sequence.  Each tuple
 * is meant to program 'value' into phy register at 'offset' with 'delay'
 * in us followed.
 */
#define HSPHY_INIT_CFG(o, v, d)	{ .offset = o, .val = v, .delay = d, }

static const struct hsphy_init_seq init_seq_femtophy[] = {
	HSPHY_INIT_CFG(0xc0, 0x01, 0),
	HSPHY_INIT_CFG(0xe8, 0x0d, 0),
	HSPHY_INIT_CFG(0x74, 0x12, 0),
	HSPHY_INIT_CFG(0x98, 0x63, 0),
	HSPHY_INIT_CFG(0x9c, 0x03, 0),
	HSPHY_INIT_CFG(0xa0, 0x1d, 0),
	HSPHY_INIT_CFG(0xa4, 0x03, 0),
	HSPHY_INIT_CFG(0x8c, 0x23, 0),
	HSPHY_INIT_CFG(0x78, 0x08, 0),
	HSPHY_INIT_CFG(0x7c, 0xdc, 0),
	HSPHY_INIT_CFG(0x90, 0xe0, 20),
	HSPHY_INIT_CFG(0x74, 0x10, 0),
	HSPHY_INIT_CFG(0x90, 0x60, 0),
};

static const struct hsphy_data data_femtophy = {
	.init_seq = init_seq_femtophy,
	.init_seq_num = ARRAY_SIZE(init_seq_femtophy),
};

static const struct udevice_id hsphy_ids[] = {
	{ .compatible = "qcom,usb-hs-28nm-femtophy", .data = (ulong)&data_femtophy },
	{ }
};

U_BOOT_DRIVER(qcom_usb_hs_28nm) = {
	.name		= "qcom-usb-hs-28nm",
	.id		= UCLASS_PHY,
	.of_match	= hsphy_ids,
	.ops		= &hsphy_ops,
	.probe		= hsphy_probe,
	.priv_auto	= sizeof(struct hsphy_priv),
};
