// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright 2020 NXP
 */

#define LOG_CATEGORY UCLASS_ETH_PHY

#include <common.h>
#include <dm.h>
#include <log.h>
#include <net.h>
#include <asm-generic/gpio.h>
#include <dm/device_compat.h>
#include <dm/device-internal.h>
#include <dm/uclass-internal.h>
#include <dm/lists.h>
#include <linux/delay.h>

struct eth_phy_device_priv {
	struct mii_dev *mdio_bus;
	struct gpio_desc reset_gpio;
	u32 reset_assert_delay;
	u32 reset_deassert_delay;
};

int eth_phy_binds_nodes(struct udevice *eth_dev)
{
	ofnode mdio_node, phy_node;
	const char *node_name;
	int ret;

	/* search a subnode named "mdio.*" */
	dev_for_each_subnode(mdio_node, eth_dev) {
		node_name = ofnode_get_name(mdio_node);
		if (!strncmp(node_name, "mdio", 4))
			break;
	}
	if (!ofnode_valid(mdio_node)) {
		dev_dbg(eth_dev, "%s: %s mdio subnode not found!\n", __func__,
			eth_dev->name);
		return -ENXIO;
	}
	dev_dbg(eth_dev, "%s: %s subnode found!\n", __func__, node_name);

	ofnode_for_each_subnode(phy_node, mdio_node) {
		node_name = ofnode_get_name(phy_node);

		dev_dbg(eth_dev, "* Found child node: '%s'\n", node_name);

		ret = device_bind_driver_to_node(eth_dev,
						 "eth_phy_generic_drv",
						 node_name, phy_node, NULL);
		if (ret) {
			dev_dbg(eth_dev, "  - Eth phy binding error: %d\n", ret);
			continue;
		}

		dev_dbg(eth_dev, "  - bound phy device: '%s'\n", node_name);
	}

	return 0;
}

int eth_phy_set_mdio_bus(struct udevice *eth_dev, struct mii_dev *mdio_bus)
{
	struct udevice *dev;
	struct eth_phy_device_priv *uc_priv;

	for (uclass_first_device(UCLASS_ETH_PHY, &dev); dev;
	     uclass_next_device(&dev)) {
		if (dev->parent == eth_dev) {
			uc_priv = (struct eth_phy_device_priv *)(dev_get_uclass_priv(dev));

			if (!uc_priv->mdio_bus)
				uc_priv->mdio_bus = mdio_bus;
		}
	}

	return 0;
}

struct mii_dev *eth_phy_get_mdio_bus(struct udevice *eth_dev)
{
	int ret;
	struct udevice *phy_dev;
	struct eth_phy_device_priv *uc_priv;

	/* Will probe the parent of phy device, then phy device */
	ret = uclass_get_device_by_phandle(UCLASS_ETH_PHY, eth_dev,
					   "phy-handle", &phy_dev);
	if (!ret) {
		if (eth_dev != phy_dev->parent) {
			/*
			 * phy_dev is shared and controlled by
			 * other eth controller
			 */
			uc_priv = (struct eth_phy_device_priv *)(dev_get_uclass_priv(phy_dev));
			if (uc_priv->mdio_bus)
				log_notice("Get shared mii bus on %s\n", eth_dev->name);
			else
				log_notice("Can't get shared mii bus on %s\n", eth_dev->name);

			return uc_priv->mdio_bus;
		}
	} else {
		log_notice("FEC: can't find phy-handle\n");
	}

	return NULL;
}

int eth_phy_get_addr(struct udevice *dev)
{
	struct ofnode_phandle_args phandle_args;
	int reg;

	if (dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0,
				       &phandle_args)) {
		dev_dbg(dev, "Failed to find phy-handle");
		return -ENODEV;
	}

	reg = ofnode_read_u32_default(phandle_args.node, "reg", 0);

	return reg;
}

/* parsing generic properties of devicetree/bindings/net/ethernet-phy.yaml */
static int eth_phy_of_to_plat(struct udevice *dev)
{
	struct eth_phy_device_priv *uc_priv = dev_get_uclass_priv(dev);
	int ret;

	if (!CONFIG_IS_ENABLED(DM_GPIO))
		return 0;

	/* search "reset-gpios" in phy node */
	ret = gpio_request_by_name(dev, "reset-gpios", 0,
				   &uc_priv->reset_gpio,
				   GPIOD_IS_OUT);
	if (ret != -ENOENT)
		return ret;

	uc_priv->reset_assert_delay = dev_read_u32_default(dev, "reset-assert-us", 0);
	uc_priv->reset_deassert_delay = dev_read_u32_default(dev, "reset-deassert-us", 0);

	return 0;
}

void eth_phy_reset(struct udevice *dev, int value)
{
	struct eth_phy_device_priv *uc_priv = dev_get_uclass_priv(dev);
	u32 delay;

	if (!CONFIG_IS_ENABLED(DM_GPIO))
		return;

	if (!dm_gpio_is_valid(&uc_priv->reset_gpio))
		return;

	dm_gpio_set_value(&uc_priv->reset_gpio, value);

	delay = value ? uc_priv->reset_assert_delay : uc_priv->reset_deassert_delay;
	if (delay)
		udelay(delay);
}

static int eth_phy_pre_probe(struct udevice *dev)
{
	/* Assert and deassert the reset signal */
	eth_phy_reset(dev, 1);
	eth_phy_reset(dev, 0);

	return 0;
}

UCLASS_DRIVER(eth_phy_generic) = {
	.id		= UCLASS_ETH_PHY,
	.name		= "eth_phy_generic",
	.per_device_auto	= sizeof(struct eth_phy_device_priv),
	.pre_probe	= eth_phy_pre_probe,
};

U_BOOT_DRIVER(eth_phy_generic_drv) = {
	.name		= "eth_phy_generic_drv",
	.id		= UCLASS_ETH_PHY,
	.of_to_plat	= eth_phy_of_to_plat,
};
