// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
 * Author(s): Patrice Chotard, <patrice.chotard@foss.st.com> for STMicroelectronics.
 */

#include <common.h>
#include <dm.h>
#include <log.h>
#include <mmc.h>
#include <reset-uclass.h>
#include <sdhci.h>
#include <asm/arch/sdhci.h>

DECLARE_GLOBAL_DATA_PTR;

struct sti_sdhci_plat {
	struct mmc_config cfg;
	struct mmc mmc;
	struct reset_ctl reset;
	int instance;
};

/**
 * sti_mmc_core_config: configure the Arasan HC
 * @dev : udevice
 *
 * Description: this function is to configure the Arasan MMC HC.
 * This should be called when the system starts in case of, on the SoC,
 * it is needed to configure the host controller.
 * This happens on some SoCs, i.e. StiH410, where the MMC0 inside the flashSS
 * needs to be configured as MMC 4.5 to have full capabilities.
 * W/o these settings the SDHCI could configure and use the embedded controller
 * with limited features.
 */
static int sti_mmc_core_config(struct udevice *dev)
{
	struct sti_sdhci_plat *plat = dev_get_plat(dev);
	struct sdhci_host *host = dev_get_priv(dev);
	int ret;

	/* only MMC1 has a reset line */
	if (plat->instance) {
		ret = reset_deassert(&plat->reset);
		if (ret < 0) {
			pr_err("MMC1 deassert failed: %d", ret);
			return ret;
		}
	}

	writel(STI_FLASHSS_MMC_CORE_CONFIG_1,
	       host->ioaddr + FLASHSS_MMC_CORE_CONFIG_1);

	if (plat->instance) {
		writel(STI_FLASHSS_MMC_CORE_CONFIG2,
		       host->ioaddr + FLASHSS_MMC_CORE_CONFIG_2);
		writel(STI_FLASHSS_MMC_CORE_CONFIG3,
		       host->ioaddr + FLASHSS_MMC_CORE_CONFIG_3);
	} else {
		writel(STI_FLASHSS_SDCARD_CORE_CONFIG2,
		       host->ioaddr + FLASHSS_MMC_CORE_CONFIG_2);
		writel(STI_FLASHSS_SDCARD_CORE_CONFIG3,
		       host->ioaddr + FLASHSS_MMC_CORE_CONFIG_3);
	}
	writel(STI_FLASHSS_MMC_CORE_CONFIG4,
	       host->ioaddr + FLASHSS_MMC_CORE_CONFIG_4);

	return 0;
}

static int sti_sdhci_probe(struct udevice *dev)
{
	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
	struct sti_sdhci_plat *plat = dev_get_plat(dev);
	struct sdhci_host *host = dev_get_priv(dev);
	int ret;

	/*
	 * identify current mmc instance, mmc1 has a reset, not mmc0
	 * MMC0 is wired to the SD slot,
	 * MMC1 is wired on the high speed connector
	 */
	ret = reset_get_by_index(dev, 0, &plat->reset);
	if (!ret)
		plat->instance = 1;
	else
		if (ret == -ENOENT)
			plat->instance = 0;
		else
			return ret;

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

	host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD |
		       SDHCI_QUIRK_32BIT_DMA_ADDR |
		       SDHCI_QUIRK_NO_HISPD_BIT;

	host->host_caps = MMC_MODE_DDR_52MHz;
	host->mmc = &plat->mmc;
	host->mmc->dev = dev;
	host->mmc->priv = host;

	ret = sdhci_setup_cfg(&plat->cfg, host, 50000000, 400000);
	if (ret)
		return ret;

	upriv->mmc = host->mmc;

	return sdhci_probe(dev);
}

static int sti_sdhci_of_to_plat(struct udevice *dev)
{
	struct sdhci_host *host = dev_get_priv(dev);

	host->name = strdup(dev->name);
	host->ioaddr = dev_read_addr_ptr(dev);

	host->bus_width = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
					 "bus-width", 4);

	return 0;
}

static int sti_sdhci_bind(struct udevice *dev)
{
	struct sti_sdhci_plat *plat = dev_get_plat(dev);

	return sdhci_bind(dev, &plat->mmc, &plat->cfg);
}

static const struct udevice_id sti_sdhci_ids[] = {
	{ .compatible = "st,sdhci" },
	{ }
};

U_BOOT_DRIVER(sti_mmc) = {
	.name = "sti_sdhci",
	.id = UCLASS_MMC,
	.of_match = sti_sdhci_ids,
	.bind = sti_sdhci_bind,
	.ops = &sdhci_ops,
	.of_to_plat = sti_sdhci_of_to_plat,
	.probe = sti_sdhci_probe,
	.priv_auto	= sizeof(struct sdhci_host),
	.plat_auto	= sizeof(struct sti_sdhci_plat),
};
