// SPDX-License-Identifier: GPL-2.0+
/*
 * USB cluster support for Armada 375 platform.
 *
 * Copyright (C) 2014 Marvell
 *
 * Gregory CLEMENT <gregory.clement@free-electrons.com>
 *
 * Armada 375 comes with an USB2 host and device controller and an
 * USB3 controller. The USB cluster control register allows to manage
 * common features of both USB controllers.
 */

#include <dt-bindings/phy/phy.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/of_address.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>

#define USB2_PHY_CONFIG_DISABLE BIT(0)

struct armada375_cluster_phy {
	struct phy *phy;
	void __iomem *reg;
	bool use_usb3;
	int phy_provided;
};

static int armada375_usb_phy_init(struct phy *phy)
{
	struct armada375_cluster_phy *cluster_phy;
	u32 reg;

	cluster_phy = phy_get_drvdata(phy);
	if (!cluster_phy)
		return -ENODEV;

	reg = readl(cluster_phy->reg);
	if (cluster_phy->use_usb3)
		reg |= USB2_PHY_CONFIG_DISABLE;
	else
		reg &= ~USB2_PHY_CONFIG_DISABLE;
	writel(reg, cluster_phy->reg);

	return 0;
}

static const struct phy_ops armada375_usb_phy_ops = {
	.init = armada375_usb_phy_init,
	.owner = THIS_MODULE,
};

/*
 * Only one controller can use this PHY. We shouldn't have the case
 * when two controllers want to use this PHY. But if this case occurs
 * then we provide a phy to the first one and return an error for the
 * next one. This error has also to be an error returned by
 * devm_phy_optional_get() so different from ENODEV for USB2. In the
 * USB3 case it still optional and we use ENODEV.
 */
static struct phy *armada375_usb_phy_xlate(struct device *dev,
					struct of_phandle_args *args)
{
	struct armada375_cluster_phy *cluster_phy = dev_get_drvdata(dev);

	if (!cluster_phy)
		return  ERR_PTR(-ENODEV);

	/*
	 * Either the phy had never been requested and then the first
	 * usb claiming it can get it, or it had already been
	 * requested in this case, we only allow to use it with the
	 * same configuration.
	 */
	if (WARN_ON((cluster_phy->phy_provided != PHY_NONE) &&
			(cluster_phy->phy_provided != args->args[0]))) {
		dev_err(dev, "This PHY has already been provided!\n");
		dev_err(dev, "Check your device tree, only one controller can use it\n.");
		if (args->args[0] == PHY_TYPE_USB2)
			return ERR_PTR(-EBUSY);
		else
			return ERR_PTR(-ENODEV);
	}

	if (args->args[0] == PHY_TYPE_USB2)
		cluster_phy->use_usb3 = false;
	else if (args->args[0] == PHY_TYPE_USB3)
		cluster_phy->use_usb3 = true;
	else {
		dev_err(dev, "Invalid PHY mode\n");
		return ERR_PTR(-ENODEV);
	}

	/* Store which phy mode is used for next test */
	cluster_phy->phy_provided = args->args[0];

	return cluster_phy->phy;
}

static int armada375_usb_phy_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct phy *phy;
	struct phy_provider *phy_provider;
	void __iomem *usb_cluster_base;
	struct resource *res;
	struct armada375_cluster_phy *cluster_phy;

	cluster_phy = devm_kzalloc(dev, sizeof(*cluster_phy), GFP_KERNEL);
	if (!cluster_phy)
		return  -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	usb_cluster_base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(usb_cluster_base))
		return PTR_ERR(usb_cluster_base);

	phy = devm_phy_create(dev, NULL, &armada375_usb_phy_ops);
	if (IS_ERR(phy)) {
		dev_err(dev, "failed to create PHY\n");
		return PTR_ERR(phy);
	}

	cluster_phy->phy = phy;
	cluster_phy->reg = usb_cluster_base;

	dev_set_drvdata(dev, cluster_phy);
	phy_set_drvdata(phy, cluster_phy);

	phy_provider = devm_of_phy_provider_register(&pdev->dev,
						     armada375_usb_phy_xlate);
	return PTR_ERR_OR_ZERO(phy_provider);
}

static const struct of_device_id of_usb_cluster_table[] = {
	{ .compatible = "marvell,armada-375-usb-cluster", },
	{ /* end of list */ },
};

static struct platform_driver armada375_usb_phy_driver = {
	.probe	= armada375_usb_phy_probe,
	.driver = {
		.of_match_table	= of_usb_cluster_table,
		.name  = "armada-375-usb-cluster",
	}
};
builtin_platform_driver(armada375_usb_phy_driver);
