// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2015 Alexey Brodkin <abrodkin@synopsys.com>
 */

#include <common.h>
#include <clk.h>
#include <log.h>
#include <dm/device_compat.h>
#include <dm/devres.h>
#include <dm/ofnode.h>
#include <generic-phy.h>
#include <reset.h>
#include <asm/io.h>
#include <dm.h>
#include "ehci.h"
#include <power/regulator.h>

/*
 * Even though here we don't explicitly use "struct ehci_ctrl"
 * ehci_register() expects it to be the first thing that resides in
 * device's private data.
 */
struct generic_ehci {
	struct ehci_ctrl ctrl;
	struct clk_bulk clocks;
	struct reset_ctl_bulk resets;
	struct phy phy;
	struct udevice *vbus_supply;
};

static int ehci_enable_vbus_supply(struct udevice *dev)
{
	struct generic_ehci *priv = dev_get_priv(dev);
	int ret;

	ret = device_get_supply_regulator(dev, "vbus-supply",
					  &priv->vbus_supply);
	if (ret && ret != -ENOENT)
		return ret;

	if (priv->vbus_supply) {
		ret = regulator_set_enable(priv->vbus_supply, true);
		if (ret) {
			dev_err(dev, "Error enabling VBUS supply (ret=%d)\n", ret);
			return ret;
		}
	} else {
		dev_dbg(dev, "No vbus supply\n");
	}

	return 0;
}

static int ehci_disable_vbus_supply(struct generic_ehci *priv)
{
	if (priv->vbus_supply)
		return regulator_set_enable(priv->vbus_supply, false);
	else
		return 0;
}

static int ehci_usb_probe(struct udevice *dev)
{
	struct generic_ehci *priv = dev_get_priv(dev);
	struct ehci_hccr *hccr;
	struct ehci_hcor *hcor;
	int err, ret;

	err = 0;
	ret = clk_get_bulk(dev, &priv->clocks);
	if (ret && ret != -ENOENT) {
		dev_err(dev, "Failed to get clocks (ret=%d)\n", ret);
		return ret;
	}

	err = clk_enable_bulk(&priv->clocks);
	if (err) {
		dev_err(dev, "Failed to enable clocks (err=%d)\n", err);
		goto clk_err;
	}

	err = reset_get_bulk(dev, &priv->resets);
	if (err && err != -ENOENT) {
		dev_err(dev, "Failed to get resets (err=%d)\n", err);
		goto clk_err;
	}

	err = reset_deassert_bulk(&priv->resets);
	if (err) {
		dev_err(dev, "Failed to get deassert resets (err=%d)\n", err);
		goto reset_err;
	}

	err = ehci_enable_vbus_supply(dev);
	if (err)
		goto reset_err;

	err = ehci_setup_phy(dev, &priv->phy, 0);
	if (err)
		goto regulator_err;

	hccr = map_physmem(dev_read_addr(dev), 0x100, MAP_NOCACHE);
	hcor = (struct ehci_hcor *)((uintptr_t)hccr +
				    HC_LENGTH(ehci_readl(&hccr->cr_capbase)));

	err = ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST);
	if (err)
		goto phy_err;

	return 0;

phy_err:
	ret = ehci_shutdown_phy(dev, &priv->phy);
	if (ret)
		dev_err(dev, "failed to shutdown usb phy (ret=%d)\n", ret);

regulator_err:
	ret = ehci_disable_vbus_supply(priv);
	if (ret)
		dev_err(dev, "failed to disable VBUS supply (ret=%d)\n", ret);

reset_err:
	ret = reset_release_bulk(&priv->resets);
	if (ret)
		dev_err(dev, "failed to release resets (ret=%d)\n", ret);
clk_err:
	ret = clk_release_bulk(&priv->clocks);
	if (ret)
		dev_err(dev, "failed to release clocks (ret=%d)\n", ret);

	return err;
}

static int ehci_usb_remove(struct udevice *dev)
{
	struct generic_ehci *priv = dev_get_priv(dev);
	int ret;

	ret = ehci_deregister(dev);
	if (ret)
		return ret;

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

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

	ret = reset_release_bulk(&priv->resets);
	if (ret)
		return ret;

	return clk_release_bulk(&priv->clocks);
}

static const struct udevice_id ehci_usb_ids[] = {
	{ .compatible = "generic-ehci" },
	{ }
};

U_BOOT_DRIVER(ehci_generic) = {
	.name	= "ehci_generic",
	.id	= UCLASS_USB,
	.of_match = ehci_usb_ids,
	.probe = ehci_usb_probe,
	.remove = ehci_usb_remove,
	.ops	= &ehci_usb_ops,
	.priv_auto	= sizeof(struct generic_ehci),
	.flags	= DM_FLAG_ALLOC_PRIV_DMA,
};
