// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2022 Marek Vasut <marex@denx.de>
 */

#include <asm/io.h>
#include <clk.h>
#include <clk-uclass.h>
#include <dm.h>
#include <dm/device.h>
#include <dm/device_compat.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
#include <linux/bitfield.h>
#include <linux/delay.h>
#include <linux/iopoll.h>
#include <power-domain-uclass.h>

#include <dt-bindings/power/imx8mp-power.h>

#define GPR_REG0		0x0
#define  PCIE_CLOCK_MODULE_EN	BIT(0)
#define  USB_CLOCK_MODULE_EN	BIT(1)
#define  PCIE_PHY_APB_RST	BIT(4)
#define  PCIE_PHY_INIT_RST	BIT(5)
#define GPR_REG1		0x4
#define  PLL_LOCK		BIT(13)
#define GPR_REG2		0x8
#define  P_PLL_MASK		GENMASK(5, 0)
#define  M_PLL_MASK		GENMASK(15, 6)
#define  S_PLL_MASK		GENMASK(18, 16)
#define GPR_REG3		0xc
#define  PLL_CKE		BIT(17)
#define  PLL_RST		BIT(31)

struct imx8mp_hsiomix_priv {
	void __iomem *base;
	struct clk clk_usb;
	struct clk clk_pcie;
	struct power_domain pd_bus;
	struct power_domain pd_usb;
	struct power_domain pd_pcie;
	struct power_domain pd_usb_phy1;
	struct power_domain pd_usb_phy2;
	struct power_domain pd_pcie_phy;
};

static int imx8mp_hsiomix_set(struct power_domain *power_domain, bool power_on)
{
	struct udevice *dev = power_domain->dev;
	struct imx8mp_hsiomix_priv *priv = dev_get_priv(dev);
	struct power_domain *domain = NULL;
	struct clk *clk = NULL;
	u32 gpr_reg0_bits = 0;
	int ret;

	switch (power_domain->id) {
	case IMX8MP_HSIOBLK_PD_USB:
		domain = &priv->pd_usb;
		clk = &priv->clk_usb;
		gpr_reg0_bits |= USB_CLOCK_MODULE_EN;
		break;
	case IMX8MP_HSIOBLK_PD_USB_PHY1:
		domain = &priv->pd_usb_phy1;
		break;
	case IMX8MP_HSIOBLK_PD_USB_PHY2:
		domain = &priv->pd_usb_phy2;
		break;
	case IMX8MP_HSIOBLK_PD_PCIE:
		domain = &priv->pd_pcie;
		clk = &priv->clk_pcie;
		gpr_reg0_bits |= PCIE_CLOCK_MODULE_EN;
		break;
	case IMX8MP_HSIOBLK_PD_PCIE_PHY:
		domain = &priv->pd_pcie_phy;
		/* Bits to deassert PCIe PHY reset */
		gpr_reg0_bits |= PCIE_PHY_APB_RST | PCIE_PHY_INIT_RST;
		break;
	default:
		dev_err(dev, "unknown power domain id: %ld\n",
			power_domain->id);
		return -EINVAL;
	}

	if (power_on) {
		ret = power_domain_on(&priv->pd_bus);
		if (ret)
			return ret;

		ret = power_domain_on(domain);
		if (ret)
			goto err_pd;

		if (clk) {
			ret = clk_enable(clk);
			if (ret)
				goto err_clk;
		}

		if (gpr_reg0_bits)
			setbits_le32(priv->base + GPR_REG0, gpr_reg0_bits);
	} else {
		if (gpr_reg0_bits)
			clrbits_le32(priv->base + GPR_REG0, gpr_reg0_bits);

		if (clk)
			clk_disable(clk);

		power_domain_off(domain);
		power_domain_off(&priv->pd_bus);
	}

	return 0;

err_clk:
	power_domain_off(domain);
err_pd:
	power_domain_off(&priv->pd_bus);
	return ret;
}

static int imx8mp_hsiomix_on(struct power_domain *power_domain)
{
	return imx8mp_hsiomix_set(power_domain, true);
}

static int imx8mp_hsiomix_off(struct power_domain *power_domain)
{
	return imx8mp_hsiomix_set(power_domain, false);
}

static int imx8mp_hsiomix_of_xlate(struct power_domain *power_domain,
				   struct ofnode_phandle_args *args)
{
	power_domain->id = args->args[0];

	return 0;
}

static int hsio_pll_clk_enable(struct clk *clk)
{
	void *base = (void *)dev_get_driver_data(clk->dev);
	u32 val;
	int ret;

	/* Setup HSIO PLL as 100 MHz output clock */
	clrsetbits_le32(base + GPR_REG2,
			P_PLL_MASK | M_PLL_MASK | S_PLL_MASK,
			FIELD_PREP(P_PLL_MASK, 12) |
			FIELD_PREP(M_PLL_MASK, 800) |
			FIELD_PREP(S_PLL_MASK, 4));

	/* de-assert PLL reset */
	setbits_le32(base + GPR_REG3, PLL_RST);

	/* enable PLL */
	setbits_le32(base + GPR_REG3, PLL_CKE);

	/* Check if PLL is locked */
	ret = readl_poll_sleep_timeout(base + GPR_REG1, val,
				       val & PLL_LOCK, 10, 100000);
	if (ret)
		dev_err(clk->dev, "failed to lock HSIO PLL\n");

	return ret;
}

static int hsio_pll_clk_disable(struct clk *clk)
{
	void *base = (void *)dev_get_driver_data(clk->dev);

	clrbits_le32(base + GPR_REG3, PLL_CKE | PLL_RST);

	return 0;
}

static const struct clk_ops hsio_pll_clk_ops = {
	.enable = hsio_pll_clk_enable,
	.disable = hsio_pll_clk_disable,
};

U_BOOT_DRIVER(hsio_pll) = {
	.name = "hsio-pll",
	.id = UCLASS_CLK,
	.ops = &hsio_pll_clk_ops,
};

int imx8mp_hsiomix_bind(struct udevice *dev)
{
	struct driver *drv;

	drv = lists_driver_lookup_name("hsio-pll");
	if (!drv)
		return -ENOENT;

	return device_bind_with_driver_data(dev, drv, "hsio-pll",
					    (ulong)dev_read_addr_ptr(dev),
					    dev_ofnode(dev), NULL);
}

static int imx8mp_hsiomix_probe(struct udevice *dev)
{
	struct imx8mp_hsiomix_priv *priv = dev_get_priv(dev);
	int ret;

	priv->base = dev_read_addr_ptr(dev);

	ret = clk_get_by_name(dev, "usb", &priv->clk_usb);
	if (ret < 0)
		return ret;

	ret = clk_get_by_name(dev, "pcie", &priv->clk_pcie);
	if (ret < 0)
		return ret;

	ret = power_domain_get_by_name(dev, &priv->pd_bus, "bus");
	if (ret < 0)
		return ret;

	ret = power_domain_get_by_name(dev, &priv->pd_usb, "usb");
	if (ret < 0)
		goto err_pd_usb;

	ret = power_domain_get_by_name(dev, &priv->pd_usb_phy1, "usb-phy1");
	if (ret < 0)
		goto err_pd_usb_phy1;

	ret = power_domain_get_by_name(dev, &priv->pd_usb_phy2, "usb-phy2");
	if (ret < 0)
		goto err_pd_usb_phy2;

	ret = power_domain_get_by_name(dev, &priv->pd_pcie, "pcie");
	if (ret < 0)
		goto err_pd_pcie;

	ret = power_domain_get_by_name(dev, &priv->pd_pcie_phy, "pcie-phy");
	if (ret < 0)
		goto err_pd_pcie_phy;

	return 0;

err_pd_pcie_phy:
	power_domain_free(&priv->pd_pcie);
err_pd_pcie:
	power_domain_free(&priv->pd_usb_phy2);
err_pd_usb_phy2:
	power_domain_free(&priv->pd_usb_phy1);
err_pd_usb_phy1:
	power_domain_free(&priv->pd_usb);
err_pd_usb:
	power_domain_free(&priv->pd_bus);
	return ret;
}

static const struct udevice_id imx8mp_hsiomix_ids[] = {
	{ .compatible = "fsl,imx8mp-hsio-blk-ctrl" },
	{ }
};

struct power_domain_ops imx8mp_hsiomix_ops = {
	.on = imx8mp_hsiomix_on,
	.off = imx8mp_hsiomix_off,
	.of_xlate = imx8mp_hsiomix_of_xlate,
};

U_BOOT_DRIVER(imx8mp_hsiomix) = {
	.name		= "imx8mp_hsiomix",
	.id		= UCLASS_POWER_DOMAIN,
	.of_match	= imx8mp_hsiomix_ids,
	.probe		= imx8mp_hsiomix_probe,
	.bind		= imx8mp_hsiomix_bind,
	.priv_auto	= sizeof(struct imx8mp_hsiomix_priv),
	.ops		= &imx8mp_hsiomix_ops,
};
