/*
 * Copyright (c) 2016 Rockchip, Inc.
 * Authors: Daniel Meng <daniel.meng@rock-chips.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */
#include <common.h>
#include <dm.h>
#include <malloc.h>
#include <usb.h>
#include <watchdog.h>
#include <linux/errno.h>
#include <linux/compat.h>
#include <linux/usb/dwc3.h>
#include <power/regulator.h>

#include "xhci.h"

DECLARE_GLOBAL_DATA_PTR;

struct rockchip_xhci_platdata {
	fdt_addr_t hcd_base;
	fdt_addr_t phy_base;
	struct udevice *vbus_supply;
};

/*
 * Contains pointers to register base addresses
 * for the usb controller.
 */
struct rockchip_xhci {
	struct usb_platdata usb_plat;
	struct xhci_ctrl ctrl;
	struct xhci_hccr *hcd;
	struct dwc3 *dwc3_reg;
};

static int xhci_usb_ofdata_to_platdata(struct udevice *dev)
{
	struct rockchip_xhci_platdata *plat = dev_get_platdata(dev);
	struct udevice *child;
	int ret = 0;

	/*
	 * Get the base address for XHCI controller from the device node
	 */
	plat->hcd_base = dev_read_addr(dev);
	if (plat->hcd_base == FDT_ADDR_T_NONE) {
		pr_err("Can't get the XHCI register base address\n");
		return -ENXIO;
	}

	/* Get the base address for usbphy from the device node */
	for (device_find_first_child(dev, &child); child;
	     device_find_next_child(&child)) {
		if (!device_is_compatible(child, "rockchip,rk3399-usb3-phy"))
			continue;
		plat->phy_base = devfdt_get_addr(child);
		break;
	}

	if (plat->phy_base == FDT_ADDR_T_NONE) {
		pr_err("Can't get the usbphy register address\n");
		return -ENXIO;
	}

	/* Vbus regulator */
	ret = device_get_supply_regulator(dev, "vbus-supply",
					  &plat->vbus_supply);
	if (ret)
		debug("Can't get VBus regulator!\n");

	return 0;
}

/*
 * rockchip_dwc3_phy_setup() - Configure USB PHY Interface of DWC3 Core
 * @dwc: Pointer to our controller context structure
 * @dev: Pointer to ulcass device
 */
static void rockchip_dwc3_phy_setup(struct dwc3 *dwc3_reg,
				    struct udevice *dev)
{
	u32 reg;
	u32 utmi_bits;

	/* Set dwc3 usb2 phy config */
	reg = readl(&dwc3_reg->g_usb2phycfg[0]);

	if (dev_read_bool(dev, "snps,dis-enblslpm-quirk"))
		reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;

	utmi_bits = dev_read_u32_default(dev, "snps,phyif-utmi-bits", -1);
	if (utmi_bits == 16) {
		reg |= DWC3_GUSB2PHYCFG_PHYIF;
		reg &= ~DWC3_GUSB2PHYCFG_USBTRDTIM_MASK;
		reg |= DWC3_GUSB2PHYCFG_USBTRDTIM_16BIT;
	} else if (utmi_bits == 8) {
		reg &= ~DWC3_GUSB2PHYCFG_PHYIF;
		reg &= ~DWC3_GUSB2PHYCFG_USBTRDTIM_MASK;
		reg |= DWC3_GUSB2PHYCFG_USBTRDTIM_8BIT;
	}

	if (dev_read_bool(dev, "snps,dis-u2-freeclk-exists-quirk"))
		reg &= ~DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS;

	if (dev_read_bool(dev, "snps,dis-u2-susphy-quirk"))
		reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;

	writel(reg, &dwc3_reg->g_usb2phycfg[0]);
}

static int rockchip_xhci_core_init(struct rockchip_xhci *rkxhci,
				   struct udevice *dev)
{
	int ret;

	ret = dwc3_core_init(rkxhci->dwc3_reg);
	if (ret) {
		pr_err("failed to initialize core\n");
		return ret;
	}

	rockchip_dwc3_phy_setup(rkxhci->dwc3_reg, dev);

	/* We are hard-coding DWC3 core to Host Mode */
	dwc3_set_mode(rkxhci->dwc3_reg, DWC3_GCTL_PRTCAP_HOST);

	return 0;
}

static int rockchip_xhci_core_exit(struct rockchip_xhci *rkxhci)
{
	return 0;
}

static int xhci_usb_probe(struct udevice *dev)
{
	struct rockchip_xhci_platdata *plat = dev_get_platdata(dev);
	struct rockchip_xhci *ctx = dev_get_priv(dev);
	struct xhci_hcor *hcor;
	int ret;

	ctx->hcd = (struct xhci_hccr *)plat->hcd_base;
	ctx->dwc3_reg = (struct dwc3 *)((char *)(ctx->hcd) + DWC3_REG_OFFSET);
	hcor = (struct xhci_hcor *)((uint64_t)ctx->hcd +
			HC_LENGTH(xhci_readl(&ctx->hcd->cr_capbase)));

	if (plat->vbus_supply) {
		ret = regulator_set_enable(plat->vbus_supply, true);
		if (ret) {
			pr_err("XHCI: failed to set VBus supply\n");
			return ret;
		}
	}

	ret = rockchip_xhci_core_init(ctx, dev);
	if (ret) {
		pr_err("XHCI: failed to initialize controller\n");
		return ret;
	}

	return xhci_register(dev, ctx->hcd, hcor);
}

static int xhci_usb_remove(struct udevice *dev)
{
	struct rockchip_xhci_platdata *plat = dev_get_platdata(dev);
	struct rockchip_xhci *ctx = dev_get_priv(dev);
	int ret;

	ret = xhci_deregister(dev);
	if (ret)
		return ret;
	ret = rockchip_xhci_core_exit(ctx);
	if (ret)
		return ret;

	if (plat->vbus_supply) {
		ret = regulator_set_enable(plat->vbus_supply, false);
		if (ret)
			pr_err("XHCI: failed to set VBus supply\n");
	}

	return ret;
}

static const struct udevice_id xhci_usb_ids[] = {
	{ .compatible = "rockchip,rk3399-xhci" },
	{ .compatible = "rockchip,rk3328-xhci" },
	{ }
};

U_BOOT_DRIVER(usb_xhci) = {
	.name	= "xhci_rockchip",
	.id	= UCLASS_USB,
	.of_match = xhci_usb_ids,
	.ofdata_to_platdata = xhci_usb_ofdata_to_platdata,
	.probe = xhci_usb_probe,
	.remove = xhci_usb_remove,
	.ops	= &xhci_usb_ops,
	.bind	= dm_scan_fdt_dev,
	.platdata_auto_alloc_size = sizeof(struct rockchip_xhci_platdata),
	.priv_auto_alloc_size = sizeof(struct rockchip_xhci),
	.flags	= DM_FLAG_ALLOC_PRIV_DMA,
};

static const struct udevice_id usb_phy_ids[] = {
	{ .compatible = "rockchip,rk3399-usb3-phy" },
	{ .compatible = "rockchip,rk3328-usb3-phy" },
	{ }
};

U_BOOT_DRIVER(usb_phy) = {
	.name = "usb_phy_rockchip",
	.of_match = usb_phy_ids,
};
