// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2017 Marek Vasut <marek.vasut@gmail.com>
 *
 * Renesas RCar USB HOST xHCI Controller
 */

#include <common.h>
#include <clk.h>
#include <dm.h>
#include <fdtdec.h>
#include <log.h>
#include <malloc.h>
#include <usb.h>
#include <wait_bit.h>
#include <dm/device_compat.h>
#include <linux/bitops.h>

#include <usb/xhci.h>
#include "xhci-rcar-r8a779x_usb3_v3.h"

/* Register Offset */
#define RCAR_USB3_DL_CTRL	0x250	/* FW Download Control & Status */
#define RCAR_USB3_FW_DATA0	0x258	/* FW Data0 */

/* Register Settings */
/* FW Download Control & Status */
#define RCAR_USB3_DL_CTRL_ENABLE	BIT(0)
#define RCAR_USB3_DL_CTRL_FW_SUCCESS	BIT(4)
#define RCAR_USB3_DL_CTRL_FW_SET_DATA0	BIT(8)

struct rcar_xhci_platdata {
	fdt_addr_t	hcd_base;
	struct clk	clk;
};

/**
 * Contains pointers to register base addresses
 * for the usb controller.
 */
struct rcar_xhci {
	struct xhci_ctrl ctrl;	/* Needs to come first in this struct! */
	struct usb_platdata usb_plat;
	struct xhci_hccr *hcd;
};

static int xhci_rcar_download_fw(struct rcar_xhci *ctx, const u32 *fw_data,
				 const size_t fw_array_size)
{
	void __iomem *regs = (void __iomem *)ctx->hcd;
	int i, ret;

	/* Download R-Car USB3.0 firmware */
	setbits_le32(regs + RCAR_USB3_DL_CTRL, RCAR_USB3_DL_CTRL_ENABLE);

	for (i = 0; i < fw_array_size; i++) {
		writel(fw_data[i], regs + RCAR_USB3_FW_DATA0);
		setbits_le32(regs + RCAR_USB3_DL_CTRL,
			     RCAR_USB3_DL_CTRL_FW_SET_DATA0);

		ret = wait_for_bit_le32(regs + RCAR_USB3_DL_CTRL,
					RCAR_USB3_DL_CTRL_FW_SET_DATA0, false,
					10, false);
		if (ret)
			break;
	}

	clrbits_le32(regs + RCAR_USB3_DL_CTRL, RCAR_USB3_DL_CTRL_ENABLE);

	ret = wait_for_bit_le32(regs + RCAR_USB3_DL_CTRL,
				RCAR_USB3_DL_CTRL_FW_SUCCESS, true,
				10, false);

	return ret;
}

static int xhci_rcar_probe(struct udevice *dev)
{
	struct rcar_xhci_platdata *plat = dev_get_platdata(dev);
	struct rcar_xhci *ctx = dev_get_priv(dev);
	struct xhci_hcor *hcor;
	int len, ret;

	ret = clk_get_by_index(dev, 0, &plat->clk);
	if (ret < 0) {
		dev_err(dev, "Failed to get USB3 clock\n");
		return ret;
	}

	ret = clk_enable(&plat->clk);
	if (ret) {
		dev_err(dev, "Failed to enable USB3 clock\n");
		goto err_clk;
	}

	ctx->hcd = (struct xhci_hccr *)plat->hcd_base;
	len = HC_LENGTH(xhci_readl(&ctx->hcd->cr_capbase));
	hcor = (struct xhci_hcor *)((uintptr_t)ctx->hcd + len);

	ret = xhci_rcar_download_fw(ctx, firmware_r8a779x_usb3_v3,
				    ARRAY_SIZE(firmware_r8a779x_usb3_v3));
	if (ret) {
		dev_err(dev, "Failed to download firmware\n");
		goto err_fw;
	}

	ret = xhci_register(dev, ctx->hcd, hcor);
	if (ret) {
		dev_err(dev, "Failed to register xHCI\n");
		goto err_fw;
	}

	return 0;

err_fw:
	clk_disable(&plat->clk);
err_clk:
	clk_free(&plat->clk);
	return ret;
}

static int xhci_rcar_deregister(struct udevice *dev)
{
	int ret;
	struct rcar_xhci_platdata *plat = dev_get_platdata(dev);

	ret = xhci_deregister(dev);

	clk_disable(&plat->clk);
	clk_free(&plat->clk);

	return ret;
}

static int xhci_rcar_ofdata_to_platdata(struct udevice *dev)
{
	struct rcar_xhci_platdata *plat = dev_get_platdata(dev);

	plat->hcd_base = dev_read_addr(dev);
	if (plat->hcd_base == FDT_ADDR_T_NONE) {
		debug("Can't get the XHCI register base address\n");
		return -ENXIO;
	}

	return 0;
}

static const struct udevice_id xhci_rcar_ids[] = {
	{ .compatible = "renesas,xhci-r8a7795" },
	{ .compatible = "renesas,xhci-r8a7796" },
	{ .compatible = "renesas,xhci-r8a77965" },
	{ }
};

U_BOOT_DRIVER(usb_xhci) = {
	.name		= "xhci_rcar",
	.id		= UCLASS_USB,
	.probe		= xhci_rcar_probe,
	.remove		= xhci_rcar_deregister,
	.ops		= &xhci_usb_ops,
	.of_match	= xhci_rcar_ids,
	.ofdata_to_platdata = xhci_rcar_ofdata_to_platdata,
	.platdata_auto_alloc_size = sizeof(struct rcar_xhci_platdata),
	.priv_auto_alloc_size = sizeof(struct rcar_xhci),
	.flags		= DM_FLAG_ALLOC_PRIV_DMA,
};
