// 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 = generic_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 = generic_shutdown_phy(&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 = generic_shutdown_phy(&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,
};
