// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2015 Linaro
 * peter.griffin <peter.griffin@linaro.org>
 */

#include <common.h>
#include <clk.h>
#include <dm.h>
#include <dwmmc.h>
#include <errno.h>
#include <fdtdec.h>
#include <malloc.h>
#include <reset.h>
#include <asm/global_data.h>
#include <dm/device_compat.h>

DECLARE_GLOBAL_DATA_PTR;

enum hi6220_dwmmc_clk_type {
	HI6220_DWMMC_CLK_BIU,
	HI6220_DWMMC_CLK_CIU,
	HI6220_DWMMC_CLK_CNT,
};

struct hi6220_dwmmc_plat {
	struct mmc_config cfg;
	struct mmc mmc;
};

struct hi6220_dwmmc_priv_data {
	struct dwmci_host host;
	struct clk *clks[HI6220_DWMMC_CLK_CNT];
	struct reset_ctl_bulk rsts;
};

struct hisi_mmc_data {
	unsigned int clock;
	bool use_fifo;
	u32 fifoth_val;
};

static int hi6220_dwmmc_of_to_plat(struct udevice *dev)
{
	struct hi6220_dwmmc_priv_data *priv = dev_get_priv(dev);
	struct dwmci_host *host = &priv->host;
	int ret;

	if (CONFIG_IS_ENABLED(CLK) && CONFIG_IS_ENABLED(DM_RESET)) {
		priv->clks[HI6220_DWMMC_CLK_BIU] = devm_clk_get(dev, "biu");
		if (IS_ERR(priv->clks[HI6220_DWMMC_CLK_BIU])) {
			ret = PTR_ERR(priv->clks[HI6220_DWMMC_CLK_BIU]);
			dev_err(dev, "Failed to get BIU clock(ret = %d).\n", ret);
			return log_msg_ret("clk", ret);
		}

		priv->clks[HI6220_DWMMC_CLK_CIU] = devm_clk_get(dev, "ciu");
		if (IS_ERR(priv->clks[HI6220_DWMMC_CLK_CIU])) {
			ret = PTR_ERR(priv->clks[HI6220_DWMMC_CLK_CIU]);
			dev_err(dev, "Failed to get CIU clock(ret = %d).\n", ret);
			return log_msg_ret("clk", ret);
		}

		ret = reset_get_bulk(dev, &priv->rsts);
		if (ret) {
			dev_err(dev, "Failed to get resets(ret = %d)", ret);
			return log_msg_ret("rst", ret);
		}
	}
	host->name = dev->name;
	host->ioaddr = dev_read_addr_ptr(dev);
	host->buswidth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
					"bus-width", 4);

	/* use non-removable property for differentiating SD card and eMMC */
	if (dev_read_bool(dev, "non-removable"))
		host->dev_index = 0;
	else
		host->dev_index = 1;

	host->priv = priv;

	return 0;
}

static int hi6220_dwmmc_probe(struct udevice *dev)
{
	struct hi6220_dwmmc_plat *plat = dev_get_plat(dev);
	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
	struct hi6220_dwmmc_priv_data *priv = dev_get_priv(dev);
	struct dwmci_host *host = &priv->host;
	struct hisi_mmc_data *mmc_data;
	int ret;

	mmc_data = (struct hisi_mmc_data *)dev_get_driver_data(dev);

	host->bus_hz = mmc_data->clock;
	if (CONFIG_IS_ENABLED(CLK) && CONFIG_IS_ENABLED(DM_RESET)) {
		ret = clk_prepare_enable(priv->clks[HI6220_DWMMC_CLK_BIU]);
		if (ret) {
			dev_err(dev, "Failed to enable biu clock(ret = %d).\n", ret);
			return log_msg_ret("clk", ret);
		}

		ret = clk_prepare_enable(priv->clks[HI6220_DWMMC_CLK_CIU]);
		if (ret) {
			dev_err(dev, "Failed to enable ciu clock(ret = %d).\n", ret);
			return log_msg_ret("clk", ret);
		}

		ret = reset_deassert_bulk(&priv->rsts);
		if (ret) {
			dev_err(dev, "Failed to deassert resets(ret = %d).\n", ret);
			return log_msg_ret("rst", ret);
		}

		host->bus_hz = clk_get_rate(priv->clks[HI6220_DWMMC_CLK_CIU]);
		if (host->bus_hz <= 0) {
			dev_err(dev, "Failed to get ciu clock rate(ret = %d).\n", ret);
			return log_msg_ret("clk", ret);
		}
	}
	dev_dbg(dev, "bus clock rate: %d.\n", host->bus_hz);

	dwmci_setup_cfg(&plat->cfg, host, host->bus_hz, 400000);
	host->mmc = &plat->mmc;

	host->fifo_mode = mmc_data->use_fifo;
	host->fifoth_val = mmc_data->fifoth_val;
	host->mmc->priv = &priv->host;
	upriv->mmc = host->mmc;
	host->mmc->dev = dev;

	return dwmci_probe(dev);
}

static int hi6220_dwmmc_bind(struct udevice *dev)
{
	struct hi6220_dwmmc_plat *plat = dev_get_plat(dev);
	int ret;

	ret = dwmci_bind(dev, &plat->mmc, &plat->cfg);
	if (ret)
		return ret;

	return 0;
}

static const struct hisi_mmc_data hi3660_mmc_data = {
	.clock = 3200000,
	.use_fifo = true,
};

static const struct hisi_mmc_data hi6220_mmc_data = {
	.clock = 50000000,
	.use_fifo = false,
};

static const struct hisi_mmc_data hi3798mv2x_mmc_data = {
	.clock = 50000000,
	.use_fifo = false,
	// FIFO depth is 256
	.fifoth_val = MSIZE(4) | RX_WMARK(0x7f) | TX_WMARK(0x80),
};

static const struct udevice_id hi6220_dwmmc_ids[] = {
	{ .compatible = "hisilicon,hi6220-dw-mshc",
	  .data = (ulong)&hi6220_mmc_data },
	{ .compatible = "hisilicon,hi3798cv200-dw-mshc",
	  .data = (ulong)&hi6220_mmc_data },
	{ .compatible = "hisilicon,hi3798mv200-dw-mshc",
	  .data = (ulong)&hi3798mv2x_mmc_data },
	{ .compatible = "hisilicon,hi3660-dw-mshc",
	  .data = (ulong)&hi3660_mmc_data },
	{ }
};

U_BOOT_DRIVER(hi6220_dwmmc_drv) = {
	.name = "hi6220_dwmmc",
	.id = UCLASS_MMC,
	.of_match = hi6220_dwmmc_ids,
	.of_to_plat = hi6220_dwmmc_of_to_plat,
	.ops = &dm_dwmci_ops,
	.bind = hi6220_dwmmc_bind,
	.probe = hi6220_dwmmc_probe,
	.priv_auto	= sizeof(struct hi6220_dwmmc_priv_data),
	.plat_auto	= sizeof(struct hi6220_dwmmc_plat),
};
