// SPDX-License-Identifier: GPL-2.0-only
// Copyright (C) 2015 Broadcom Corporation

#include <linux/delay.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>

#define PCIE_CFG_OFFSET         0x00
#define PCIE1_PHY_IDDQ_SHIFT    10
#define PCIE0_PHY_IDDQ_SHIFT    2

enum cygnus_pcie_phy_id {
	CYGNUS_PHY_PCIE0 = 0,
	CYGNUS_PHY_PCIE1,
	MAX_NUM_PHYS,
};

struct cygnus_pcie_phy_core;

/**
 * struct cygnus_pcie_phy - Cygnus PCIe PHY device
 * @core: pointer to the Cygnus PCIe PHY core control
 * @id: internal ID to identify the Cygnus PCIe PHY
 * @phy: pointer to the kernel PHY device
 */
struct cygnus_pcie_phy {
	struct cygnus_pcie_phy_core *core;
	enum cygnus_pcie_phy_id id;
	struct phy *phy;
};

/**
 * struct cygnus_pcie_phy_core - Cygnus PCIe PHY core control
 * @dev: pointer to device
 * @base: base register
 * @lock: mutex to protect access to individual PHYs
 * @phys: pointer to Cygnus PHY device
 */
struct cygnus_pcie_phy_core {
	struct device *dev;
	void __iomem *base;
	struct mutex lock;
	struct cygnus_pcie_phy phys[MAX_NUM_PHYS];
};

static int cygnus_pcie_power_config(struct cygnus_pcie_phy *phy, bool enable)
{
	struct cygnus_pcie_phy_core *core = phy->core;
	unsigned shift;
	u32 val;

	mutex_lock(&core->lock);

	switch (phy->id) {
	case CYGNUS_PHY_PCIE0:
		shift = PCIE0_PHY_IDDQ_SHIFT;
		break;

	case CYGNUS_PHY_PCIE1:
		shift = PCIE1_PHY_IDDQ_SHIFT;
		break;

	default:
		mutex_unlock(&core->lock);
		dev_err(core->dev, "PCIe PHY %d invalid\n", phy->id);
		return -EINVAL;
	}

	if (enable) {
		val = readl(core->base + PCIE_CFG_OFFSET);
		val &= ~BIT(shift);
		writel(val, core->base + PCIE_CFG_OFFSET);
		/*
		 * Wait 50 ms for the PCIe Serdes to stabilize after the analog
		 * front end is brought up
		 */
		msleep(50);
	} else {
		val = readl(core->base + PCIE_CFG_OFFSET);
		val |= BIT(shift);
		writel(val, core->base + PCIE_CFG_OFFSET);
	}

	mutex_unlock(&core->lock);
	dev_dbg(core->dev, "PCIe PHY %d %s\n", phy->id,
		enable ? "enabled" : "disabled");
	return 0;
}

static int cygnus_pcie_phy_power_on(struct phy *p)
{
	struct cygnus_pcie_phy *phy = phy_get_drvdata(p);

	return cygnus_pcie_power_config(phy, true);
}

static int cygnus_pcie_phy_power_off(struct phy *p)
{
	struct cygnus_pcie_phy *phy = phy_get_drvdata(p);

	return cygnus_pcie_power_config(phy, false);
}

static const struct phy_ops cygnus_pcie_phy_ops = {
	.power_on = cygnus_pcie_phy_power_on,
	.power_off = cygnus_pcie_phy_power_off,
	.owner = THIS_MODULE,
};

static int cygnus_pcie_phy_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *node = dev->of_node, *child;
	struct cygnus_pcie_phy_core *core;
	struct phy_provider *provider;
	unsigned cnt = 0;
	int ret;

	if (of_get_child_count(node) == 0) {
		dev_err(dev, "PHY no child node\n");
		return -ENODEV;
	}

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

	core->dev = dev;

	core->base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(core->base))
		return PTR_ERR(core->base);

	mutex_init(&core->lock);

	for_each_available_child_of_node(node, child) {
		unsigned int id;
		struct cygnus_pcie_phy *p;

		if (of_property_read_u32(child, "reg", &id)) {
			dev_err(dev, "missing reg property for %pOFn\n",
				child);
			ret = -EINVAL;
			goto put_child;
		}

		if (id >= MAX_NUM_PHYS) {
			dev_err(dev, "invalid PHY id: %u\n", id);
			ret = -EINVAL;
			goto put_child;
		}

		if (core->phys[id].phy) {
			dev_err(dev, "duplicated PHY id: %u\n", id);
			ret = -EINVAL;
			goto put_child;
		}

		p = &core->phys[id];
		p->phy = devm_phy_create(dev, child, &cygnus_pcie_phy_ops);
		if (IS_ERR(p->phy)) {
			dev_err(dev, "failed to create PHY\n");
			ret = PTR_ERR(p->phy);
			goto put_child;
		}

		p->core = core;
		p->id = id;
		phy_set_drvdata(p->phy, p);
		cnt++;
	}

	dev_set_drvdata(dev, core);

	provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
	if (IS_ERR(provider)) {
		dev_err(dev, "failed to register PHY provider\n");
		return PTR_ERR(provider);
	}

	dev_dbg(dev, "registered %u PCIe PHY(s)\n", cnt);

	return 0;
put_child:
	of_node_put(child);
	return ret;
}

static const struct of_device_id cygnus_pcie_phy_match_table[] = {
	{ .compatible = "brcm,cygnus-pcie-phy" },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, cygnus_pcie_phy_match_table);

static struct platform_driver cygnus_pcie_phy_driver = {
	.driver = {
		.name = "cygnus-pcie-phy",
		.of_match_table = cygnus_pcie_phy_match_table,
	},
	.probe = cygnus_pcie_phy_probe,
};
module_platform_driver(cygnus_pcie_phy_driver);

MODULE_AUTHOR("Ray Jui <rjui@broadcom.com>");
MODULE_DESCRIPTION("Broadcom Cygnus PCIe PHY driver");
MODULE_LICENSE("GPL v2");
