// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright 2007, 2010-2011 Freescale Semiconductor, Inc
 * Copyright 2019, 2021 NXP
 * Andy Fleming
 * Yangbo Lu <yangbo.lu@nxp.com>
 *
 * Based vaguely on the pxa mmc code:
 * (C) Copyright 2003
 * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
 */

#include <config.h>
#include <command.h>
#include <clk.h>
#include <cpu_func.h>
#include <errno.h>
#include <hwconfig.h>
#include <log.h>
#include <mmc.h>
#include <part.h>
#include <asm/cache.h>
#include <asm/global_data.h>
#include <dm/device_compat.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/printk.h>
#include <power/regulator.h>
#include <malloc.h>
#include <fsl_esdhc_imx.h>
#include <fdt_support.h>
#include <asm/io.h>
#include <dm.h>
#include <asm-generic/gpio.h>
#include <dm/pinctrl.h>
#include <dt-structs.h>
#include <mapmem.h>
#include <dm/ofnode.h>
#include <linux/iopoll.h>
#include <linux/dma-mapping.h>

#ifndef ESDHCI_QUIRK_BROKEN_TIMEOUT_VALUE
#ifdef CONFIG_FSL_USDHC
#define ESDHCI_QUIRK_BROKEN_TIMEOUT_VALUE	1
#endif
#endif

DECLARE_GLOBAL_DATA_PTR;

#define SDHCI_IRQ_EN_BITS		(IRQSTATEN_CC | IRQSTATEN_TC | \
				IRQSTATEN_CINT | \
				IRQSTATEN_CTOE | IRQSTATEN_CCE | IRQSTATEN_CEBE | \
				IRQSTATEN_CIE | IRQSTATEN_DTOE | IRQSTATEN_DCE | \
				IRQSTATEN_DEBE | IRQSTATEN_BRR | IRQSTATEN_BWR | \
				IRQSTATEN_DINT)
#define MAX_TUNING_LOOP 40

struct fsl_esdhc {
	uint    dsaddr;		/* SDMA system address register */
	uint    blkattr;	/* Block attributes register */
	uint    cmdarg;		/* Command argument register */
	uint    xfertyp;	/* Transfer type register */
	uint    cmdrsp0;	/* Command response 0 register */
	uint    cmdrsp1;	/* Command response 1 register */
	uint    cmdrsp2;	/* Command response 2 register */
	uint    cmdrsp3;	/* Command response 3 register */
	uint    datport;	/* Buffer data port register */
	uint    prsstat;	/* Present state register */
	uint    proctl;		/* Protocol control register */
	uint    sysctl;		/* System Control Register */
	uint    irqstat;	/* Interrupt status register */
	uint    irqstaten;	/* Interrupt status enable register */
	uint    irqsigen;	/* Interrupt signal enable register */
	uint    autoc12err;	/* Auto CMD error status register */
	uint    hostcapblt;	/* Host controller capabilities register */
	uint    wml;		/* Watermark level register */
	uint    mixctrl;	/* For USDHC */
	char    reserved1[4];	/* reserved */
	uint    fevt;		/* Force event register */
	uint    admaes;		/* ADMA error status register */
	uint    adsaddr;	/* ADMA system address register */
	char    reserved2[4];
	uint    dllctrl;
	uint    dllstat;
	uint    clktunectrlstatus;
	char    reserved3[4];
	uint	strobe_dllctrl;
	uint	strobe_dllstat;
	char    reserved4[72];
	uint    vendorspec;
	uint    mmcboot;
	uint    vendorspec2;
	uint    tuning_ctrl;	/* on i.MX6/7/8/RT */
	char	reserved5[44];
	uint    hostver;	/* Host controller version register */
	char    reserved6[4];	/* reserved */
	uint    dmaerraddr;	/* DMA error address register */
	char    reserved7[4];	/* reserved */
	uint    dmaerrattr;	/* DMA error attribute register */
	char    reserved8[4];	/* reserved */
	uint    hostcapblt2;	/* Host controller capabilities register 2 */
	char    reserved9[8];	/* reserved */
	uint    tcr;		/* Tuning control register */
	char    reserved10[28];	/* reserved */
	uint    sddirctl;	/* SD direction control register */
	char    reserved11[712];/* reserved */
	uint    scr;		/* eSDHC control register */
};

struct fsl_esdhc_plat {
#if CONFIG_IS_ENABLED(OF_PLATDATA)
	/* Put this first since driver model will copy the data here */
	struct dtd_fsl_esdhc dtplat;
#endif

	struct mmc_config cfg;
	struct mmc mmc;
};

struct esdhc_soc_data {
	u32 flags;
};

/**
 * struct fsl_esdhc_priv
 *
 * @esdhc_regs: registers of the sdhc controller
 * @sdhc_clk: Current clk of the sdhc controller
 * @cfg: mmc config
 * @mmc: mmc
 * Following is used when Driver Model is enabled for MMC
 * @dev: pointer for the device
 * @broken_cd: 0: use GPIO for card detect; 1: Do not use GPIO for card detect
 * @wp_enable: 1: enable checking wp; 0: no check
 * @vs18_enable: 1: use 1.8V voltage; 0: use 3.3V
 * @flags: ESDHC_FLAG_xx in include/fsl_esdhc_imx.h
 * @caps: controller capabilities
 * @tuning_step: tuning step setting in tuning_ctrl register
 * @start_tuning_tap: the start point for tuning in tuning_ctrl register
 * @strobe_dll_delay_target: settings in strobe_dllctrl
 * @signal_voltage: indicating the current voltage
 * @signal_voltage_switch_extra_delay_ms: extra delay for IO voltage switch
 * @cd_gpio: gpio for card detection
 * @wp_gpio: gpio for write protection
 */
struct fsl_esdhc_priv {
	struct fsl_esdhc *esdhc_regs;
	unsigned int sdhc_clk;
	struct clk per_clk;
	unsigned int clock;
	unsigned int mode;
#if !CONFIG_IS_ENABLED(DM_MMC)
	struct mmc *mmc;
#endif
	struct udevice *dev;
	int broken_cd;
	int wp_enable;
	int vs18_enable;
	u32 flags;
	u32 caps;
	u32 tuning_step;
	u32 tuning_start_tap;
	u32 strobe_dll_delay_target;
	u32 signal_voltage;
	u32 signal_voltage_switch_extra_delay_ms;
	struct udevice *vqmmc_dev;
	struct udevice *vmmc_dev;
#if CONFIG_IS_ENABLED(DM_GPIO)
	struct gpio_desc cd_gpio;
	struct gpio_desc wp_gpio;
#endif
	dma_addr_t dma_addr;
};

/* Return the XFERTYP flags for a given command and data packet */
static uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data)
{
	uint xfertyp = 0;

	if (data) {
		xfertyp |= XFERTYP_DPSEL;
		if (!IS_ENABLED(CONFIG_SYS_FSL_ESDHC_USE_PIO) &&
		    cmd->cmdidx != MMC_CMD_SEND_TUNING_BLOCK &&
		    cmd->cmdidx != MMC_CMD_SEND_TUNING_BLOCK_HS200)
			xfertyp |= XFERTYP_DMAEN;
		if (data->blocks > 1) {
			xfertyp |= XFERTYP_MSBSEL;
			xfertyp |= XFERTYP_BCEN;
			if (IS_ENABLED(CONFIG_SYS_FSL_ERRATUM_ESDHC111))
				xfertyp |= XFERTYP_AC12EN;
		}

		if (data->flags & MMC_DATA_READ)
			xfertyp |= XFERTYP_DTDSEL;
	}

	if (cmd->resp_type & MMC_RSP_CRC)
		xfertyp |= XFERTYP_CCCEN;
	if (cmd->resp_type & MMC_RSP_OPCODE)
		xfertyp |= XFERTYP_CICEN;
	if (cmd->resp_type & MMC_RSP_136)
		xfertyp |= XFERTYP_RSPTYP_136;
	else if (cmd->resp_type & MMC_RSP_BUSY)
		xfertyp |= XFERTYP_RSPTYP_48_BUSY;
	else if (cmd->resp_type & MMC_RSP_PRESENT)
		xfertyp |= XFERTYP_RSPTYP_48;

	if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
		xfertyp |= XFERTYP_CMDTYP_ABORT;

	return XFERTYP_CMD(cmd->cmdidx) | xfertyp;
}

/*
 * PIO Read/Write Mode reduce the performace as DMA is not used in this mode.
 */
static void esdhc_pio_read_write(struct fsl_esdhc_priv *priv,
				 struct mmc_data *data)
{
	struct fsl_esdhc *regs = priv->esdhc_regs;
	uint blocks;
	char *buffer;
	uint databuf;
	uint size;
	uint irqstat;
	ulong start;

	if (data->flags & MMC_DATA_READ) {
		blocks = data->blocks;
		buffer = data->dest;
		while (blocks) {
			start = get_timer(0);
			size = data->blocksize;
			irqstat = esdhc_read32(&regs->irqstat);
			while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_BREN)) {
				if (get_timer(start) > PIO_TIMEOUT) {
					printf("\nData Read Failed in PIO Mode.");
					return;
				}
			}
			while (size && (!(irqstat & IRQSTAT_TC))) {
				udelay(100); /* Wait before last byte transfer complete */
				irqstat = esdhc_read32(&regs->irqstat);
				databuf = in_le32(&regs->datport);
				*((uint *)buffer) = databuf;
				buffer += 4;
				size -= 4;
			}
			blocks--;
		}
	} else {
		blocks = data->blocks;
		buffer = (char *)data->src;
		while (blocks) {
			start = get_timer(0);
			size = data->blocksize;
			irqstat = esdhc_read32(&regs->irqstat);
			while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_BWEN)) {
				if (get_timer(start) > PIO_TIMEOUT) {
					printf("\nData Write Failed in PIO Mode.");
					return;
				}
			}
			while (size && (!(irqstat & IRQSTAT_TC))) {
				udelay(100); /* Wait before last byte transfer complete */
				databuf = *((uint *)buffer);
				buffer += 4;
				size -= 4;
				irqstat = esdhc_read32(&regs->irqstat);
				out_le32(&regs->datport, databuf);
			}
			blocks--;
		}
	}
}

static void esdhc_setup_watermark_level(struct fsl_esdhc_priv *priv,
					struct mmc_data *data)
{
	struct fsl_esdhc *regs = priv->esdhc_regs;
	uint wml_value = data->blocksize / 4;

	if (data->flags & MMC_DATA_READ) {
		if (wml_value > WML_RD_WML_MAX)
			wml_value = WML_RD_WML_MAX_VAL;

		esdhc_clrsetbits32(&regs->wml, WML_RD_WML_MASK, wml_value);
	} else {
		if (wml_value > WML_WR_WML_MAX)
			wml_value = WML_WR_WML_MAX_VAL;

		esdhc_clrsetbits32(&regs->wml, WML_WR_WML_MASK,
				   wml_value << 16);
	}
}

static void esdhc_setup_dma(struct fsl_esdhc_priv *priv, struct mmc_data *data)
{
	uint trans_bytes = data->blocksize * data->blocks;
	struct fsl_esdhc *regs = priv->esdhc_regs;
	void *buf;

	if (data->flags & MMC_DATA_WRITE)
		buf = (void *)data->src;
	else
		buf = data->dest;

	priv->dma_addr = dma_map_single(buf, trans_bytes,
					mmc_get_dma_dir(data));
	if (upper_32_bits(priv->dma_addr))
		printf("Cannot use 64 bit addresses with SDMA\n");
	esdhc_write32(&regs->dsaddr, lower_32_bits(priv->dma_addr));
	esdhc_write32(&regs->blkattr, data->blocks << 16 | data->blocksize);
}

static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc,
			    struct mmc_data *data)
{
	int timeout;
	bool is_write = data->flags & MMC_DATA_WRITE;
	struct fsl_esdhc *regs = priv->esdhc_regs;

	if (is_write) {
		if (priv->wp_enable && !(esdhc_read32(&regs->prsstat) & PRSSTAT_WPSPL)) {
			printf("Cannot write to locked SD card.\n");
			return -EINVAL;
		} else {
#if CONFIG_IS_ENABLED(DM_GPIO)
			if (dm_gpio_is_valid(&priv->wp_gpio) &&
			    dm_gpio_get_value(&priv->wp_gpio)) {
				printf("Cannot write to locked SD card.\n");
				return -EINVAL;
			}
#endif
		}
	}

	esdhc_setup_watermark_level(priv, data);
	if (!IS_ENABLED(CONFIG_SYS_FSL_ESDHC_USE_PIO))
		esdhc_setup_dma(priv, data);

	/* Calculate the timeout period for data transactions */
	/*
	 * 1)Timeout period = (2^(timeout+13)) SD Clock cycles
	 * 2)Timeout period should be minimum 0.250sec as per SD Card spec
	 *  So, Number of SD Clock cycles for 0.25sec should be minimum
	 *		(SD Clock/sec * 0.25 sec) SD Clock cycles
	 *		= (mmc->clock * 1/4) SD Clock cycles
	 * As 1) >=  2)
	 * => (2^(timeout+13)) >= mmc->clock * 1/4
	 * Taking log2 both the sides
	 * => timeout + 13 >= log2(mmc->clock/4)
	 * Rounding up to next power of 2
	 * => timeout + 13 = log2(mmc->clock/4) + 1
	 * => timeout + 13 = fls(mmc->clock/4)
	 *
	 * However, the MMC spec "It is strongly recommended for hosts to
	 * implement more than 500ms timeout value even if the card
	 * indicates the 250ms maximum busy length."  Even the previous
	 * value of 300ms is known to be insufficient for some cards.
	 * So, we use
	 * => timeout + 13 = fls(mmc->clock/2)
	 */
	timeout = fls(mmc->clock/2);
	timeout -= 13;

	if (timeout > 14)
		timeout = 14;

	if (timeout < 0)
		timeout = 0;

	if (IS_ENABLED(CONFIG_SYS_FSL_ERRATUM_ESDHC_A001) &&
	    (timeout == 4 || timeout == 8 || timeout == 12))
		timeout++;

	if (IS_ENABLED(ESDHCI_QUIRK_BROKEN_TIMEOUT_VALUE))
		timeout = 0xE;

	esdhc_clrsetbits32(&regs->sysctl, SYSCTL_TIMEOUT_MASK, timeout << 16);

	return 0;
}

#if IS_ENABLED(CONFIG_MCF5441x)
/*
 * Swaps 32-bit words to little-endian byte order.
 */
static inline void sd_swap_dma_buff(struct mmc_data *data)
{
	int i, size = data->blocksize >> 2;
	u32 *buffer = (u32 *)data->dest;
	u32 sw;

	while (data->blocks--) {
		for (i = 0; i < size; i++) {
			sw = __sw32(*buffer);
			*buffer++ = sw;
		}
	}
}
#else
static inline void sd_swap_dma_buff(struct mmc_data *data)
{
	return;
}
#endif

/*
 * Sends a command out on the bus.  Takes the mmc pointer,
 * a command pointer, and an optional data pointer.
 */
static int esdhc_send_cmd_common(struct fsl_esdhc_priv *priv, struct mmc *mmc,
				 struct mmc_cmd *cmd, struct mmc_data *data)
{
	int	err = 0;
	uint	xfertyp;
	uint	irqstat;
	u32	flags = IRQSTAT_CC | IRQSTAT_CTOE;
	struct fsl_esdhc *regs = priv->esdhc_regs;
	unsigned long start;

	if (IS_ENABLED(CONFIG_SYS_FSL_ERRATUM_ESDHC111) &&
	    cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
		return 0;

	esdhc_write32(&regs->irqstat, -1);

	sync();

	/* Wait for the bus to be idle */
	while ((esdhc_read32(&regs->prsstat) & PRSSTAT_CICHB) ||
			(esdhc_read32(&regs->prsstat) & PRSSTAT_CIDHB))
		;

	while (esdhc_read32(&regs->prsstat) & PRSSTAT_DLA)
		;

	/* Set up for a data transfer if we have one */
	if (data) {
		err = esdhc_setup_data(priv, mmc, data);
		if(err)
			return err;
	}

	/* Figure out the transfer arguments */
	xfertyp = esdhc_xfertyp(cmd, data);

	/* Mask all irqs */
	esdhc_write32(&regs->irqsigen, 0);

	/* Send the command */
	esdhc_write32(&regs->cmdarg, cmd->cmdarg);
	if (IS_ENABLED(CONFIG_FSL_USDHC)) {
		u32 mixctrl = esdhc_read32(&regs->mixctrl);

		esdhc_write32(&regs->mixctrl,
			      (mixctrl & 0xFFFFFF80) | (xfertyp & 0x7F)
			      | (mmc->ddr_mode ? XFERTYP_DDREN : 0));
		esdhc_write32(&regs->xfertyp, xfertyp & 0xFFFF0000);
	} else {
		esdhc_write32(&regs->xfertyp, xfertyp);
	}

	if ((cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK) ||
	    (cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200))
		flags = IRQSTAT_BRR;

	/* Wait for the command to complete */
	start = get_timer(0);
	while (!(esdhc_read32(&regs->irqstat) & flags)) {
		if (get_timer(start) > 1000) {
			err = -ETIMEDOUT;
			goto out;
		}
	}

	irqstat = esdhc_read32(&regs->irqstat);

	if (irqstat & CMD_ERR) {
		err = -ECOMM;
		goto out;
	}

	if (irqstat & IRQSTAT_CTOE) {
		err = -ETIMEDOUT;
		goto out;
	}

	/* Workaround for ESDHC errata ENGcm03648 */
	if (!data && (cmd->resp_type & MMC_RSP_BUSY)) {
		int timeout = 50000;

		/* Poll on DATA0 line for cmd with busy signal for 5000 ms */
		while (timeout > 0 && !(esdhc_read32(&regs->prsstat) &
					PRSSTAT_DAT0)) {
			udelay(100);
			timeout--;
		}

		if (timeout <= 0) {
			printf("Timeout waiting for DAT0 to go high!\n");
			err = -ETIMEDOUT;
			goto out;
		}
	}

	/* Copy the response to the response buffer */
	if (cmd->resp_type & MMC_RSP_136) {
		u32 cmdrsp3, cmdrsp2, cmdrsp1, cmdrsp0;

		cmdrsp3 = esdhc_read32(&regs->cmdrsp3);
		cmdrsp2 = esdhc_read32(&regs->cmdrsp2);
		cmdrsp1 = esdhc_read32(&regs->cmdrsp1);
		cmdrsp0 = esdhc_read32(&regs->cmdrsp0);
		cmd->response[0] = (cmdrsp3 << 8) | (cmdrsp2 >> 24);
		cmd->response[1] = (cmdrsp2 << 8) | (cmdrsp1 >> 24);
		cmd->response[2] = (cmdrsp1 << 8) | (cmdrsp0 >> 24);
		cmd->response[3] = (cmdrsp0 << 8);
	} else
		cmd->response[0] = esdhc_read32(&regs->cmdrsp0);

	/* Wait until all of the blocks are transferred */
	if (data) {
		if (IS_ENABLED(CONFIG_SYS_FSL_ESDHC_USE_PIO)) {
			esdhc_pio_read_write(priv, data);
		} else {
			flags = DATA_COMPLETE;
			if (cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK ||
			    cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200)
				flags = IRQSTAT_BRR;

			do {
				irqstat = esdhc_read32(&regs->irqstat);

				if (irqstat & IRQSTAT_DTOE) {
					err = -ETIMEDOUT;
					goto out;
				}

				if (irqstat & DATA_ERR) {
					err = -ECOMM;
					goto out;
				}
			} while ((irqstat & flags) != flags);

			/*
			 * Need invalidate the dcache here again to avoid any
			 * cache-fill during the DMA operations such as the
			 * speculative pre-fetching etc.
			 */
			dma_unmap_single(priv->dma_addr,
					 data->blocks * data->blocksize,
					 mmc_get_dma_dir(data));
			if (IS_ENABLED(CONFIG_MCF5441x) &&
			    (data->flags & MMC_DATA_READ))
				sd_swap_dma_buff(data);
		}
	}

out:
	/* Reset CMD and DATA portions on error */
	if (err) {
		esdhc_write32(&regs->sysctl, esdhc_read32(&regs->sysctl) |
			      SYSCTL_RSTC);
		while (esdhc_read32(&regs->sysctl) & SYSCTL_RSTC)
			;

		if (data) {
			esdhc_write32(&regs->sysctl,
				      esdhc_read32(&regs->sysctl) |
				      SYSCTL_RSTD);
			while ((esdhc_read32(&regs->sysctl) & SYSCTL_RSTD))
				;
		}

		/* If this was CMD11, then notify that power cycle is needed */
		if (cmd->cmdidx == SD_CMD_SWITCH_UHS18V)
			printf("CMD11 to switch to 1.8V mode failed, card requires power cycle.\n");
	}

	esdhc_write32(&regs->irqstat, -1);

	return err;
}

static void set_sysctl(struct fsl_esdhc_priv *priv, struct mmc *mmc, uint clock)
{
	struct fsl_esdhc *regs = priv->esdhc_regs;
	int div = 1;
	u32 tmp;
	int ret, pre_div;
	int ddr_pre_div = mmc->ddr_mode ? 2 : 1;
	int sdhc_clk = priv->sdhc_clk;
	uint clk;

#if IS_ENABLED(CONFIG_MX53)
	/* For i.MX53 eSDHCv3, SYSCTL.SDCLKFS may not be set to 0. */
	pre_div = (regs == (struct fsl_esdhc *)MMC_SDHC3_BASE_ADDR) ? 2 : 1;
#else
	pre_div = 1;
#endif

	while (sdhc_clk / (16 * pre_div * ddr_pre_div) > clock && pre_div < 256)
		pre_div *= 2;

	while (sdhc_clk / (div * pre_div * ddr_pre_div) > clock && div < 16)
		div++;

	mmc->clock = sdhc_clk / pre_div / div / ddr_pre_div;

	pre_div >>= 1;
	div -= 1;

	clk = (pre_div << 8) | (div << 4);

	if (IS_ENABLED(CONFIG_FSL_USDHC))
		esdhc_clrbits32(&regs->vendorspec, VENDORSPEC_CKEN);
	else
		esdhc_clrbits32(&regs->sysctl, SYSCTL_CKEN);

	esdhc_clrsetbits32(&regs->sysctl, SYSCTL_CLOCK_MASK, clk);

	ret = readx_poll_timeout(esdhc_read32, &regs->prsstat, tmp, tmp & PRSSTAT_SDSTB, 100);
	if (ret)
		pr_warn("fsl_esdhc_imx: Internal clock never stabilised.\n");

	if (IS_ENABLED(CONFIG_FSL_USDHC))
		esdhc_setbits32(&regs->vendorspec, VENDORSPEC_PEREN | VENDORSPEC_CKEN);
	else
		esdhc_setbits32(&regs->sysctl, SYSCTL_PEREN | SYSCTL_CKEN);

	priv->clock = clock;
}

#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING)
static int esdhc_change_pinstate(struct udevice *dev)
{
	struct fsl_esdhc_priv *priv = dev_get_priv(dev);
	int ret;

	switch (priv->mode) {
	case UHS_SDR50:
	case UHS_DDR50:
		ret = pinctrl_select_state(dev, "state_100mhz");
		break;
	case UHS_SDR104:
	case MMC_HS_200:
	case MMC_HS_400:
	case MMC_HS_400_ES:
		ret = pinctrl_select_state(dev, "state_200mhz");
		break;
	default:
		ret = pinctrl_select_state(dev, "default");
		break;
	}

	if (ret)
		printf("%s %d error\n", __func__, priv->mode);

	return ret;
}

static void esdhc_reset_tuning(struct mmc *mmc)
{
	struct fsl_esdhc_priv *priv = dev_get_priv(mmc->dev);
	struct fsl_esdhc *regs = priv->esdhc_regs;

	if (priv->flags & ESDHC_FLAG_USDHC) {
		if (priv->flags & ESDHC_FLAG_STD_TUNING) {
			esdhc_clrbits32(&regs->autoc12err,
					MIX_CTRL_SMPCLK_SEL |
					MIX_CTRL_EXE_TUNE);
		}
	}
}

static void esdhc_set_strobe_dll(struct mmc *mmc)
{
	struct fsl_esdhc_priv *priv = dev_get_priv(mmc->dev);
	struct fsl_esdhc *regs = priv->esdhc_regs;
	u32 val;

	if (priv->clock > ESDHC_STROBE_DLL_CLK_FREQ) {
		esdhc_write32(&regs->strobe_dllctrl, ESDHC_STROBE_DLL_CTRL_RESET);
		/* clear the reset bit on strobe dll before any setting */
		esdhc_write32(&regs->strobe_dllctrl, 0);

		/*
		 * enable strobe dll ctrl and adjust the delay target
		 * for the uSDHC loopback read clock
		 */
		val = ESDHC_STROBE_DLL_CTRL_ENABLE |
			ESDHC_STROBE_DLL_CTRL_SLV_UPDATE_INT_DEFAULT |
			(priv->strobe_dll_delay_target <<
			 ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT);
		esdhc_write32(&regs->strobe_dllctrl, val);
		/* wait 5us to make sure strobe dll status register stable */
		mdelay(5);
		val = esdhc_read32(&regs->strobe_dllstat);
		if (!(val & ESDHC_STROBE_DLL_STS_REF_LOCK))
			pr_warn("HS400 strobe DLL status REF not lock!\n");
		if (!(val & ESDHC_STROBE_DLL_STS_SLV_LOCK))
			pr_warn("HS400 strobe DLL status SLV not lock!\n");
	}
}

static int esdhc_set_timing(struct mmc *mmc)
{
	struct fsl_esdhc_priv *priv = dev_get_priv(mmc->dev);
	struct fsl_esdhc *regs = priv->esdhc_regs;
	u32 mixctrl;

	mixctrl = esdhc_read32(&regs->mixctrl);
	mixctrl &= ~(MIX_CTRL_DDREN | MIX_CTRL_HS400_EN);

	switch (mmc->selected_mode) {
	case MMC_LEGACY:
		esdhc_reset_tuning(mmc);
		esdhc_write32(&regs->mixctrl, mixctrl);
		break;
	case MMC_HS_400:
	case MMC_HS_400_ES:
		mixctrl |= MIX_CTRL_DDREN | MIX_CTRL_HS400_EN;
		esdhc_write32(&regs->mixctrl, mixctrl);
		break;
	case MMC_HS:
	case MMC_HS_52:
	case MMC_HS_200:
	case SD_HS:
	case UHS_SDR12:
	case UHS_SDR25:
	case UHS_SDR50:
	case UHS_SDR104:
		esdhc_write32(&regs->mixctrl, mixctrl);
		break;
	case UHS_DDR50:
	case MMC_DDR_52:
		mixctrl |= MIX_CTRL_DDREN;
		esdhc_write32(&regs->mixctrl, mixctrl);
		break;
	default:
		printf("Not supported %d\n", mmc->selected_mode);
		return -EINVAL;
	}

	priv->mode = mmc->selected_mode;

	return esdhc_change_pinstate(mmc->dev);
}

static int esdhc_set_voltage(struct mmc *mmc)
{
	struct fsl_esdhc_priv *priv = dev_get_priv(mmc->dev);
	struct fsl_esdhc *regs = priv->esdhc_regs;
	int ret;

	priv->signal_voltage = mmc->signal_voltage;
	switch (mmc->signal_voltage) {
	case MMC_SIGNAL_VOLTAGE_330:
		if (priv->vs18_enable)
			return -ENOTSUPP;
		if (CONFIG_IS_ENABLED(DM_REGULATOR) &&
		    !IS_ERR_OR_NULL(priv->vqmmc_dev)) {
			ret = regulator_set_value(priv->vqmmc_dev,
						  3300000);
			if (ret) {
				printf("Setting to 3.3V error");
				return -EIO;
			}
			mdelay(5);
		}

		esdhc_clrbits32(&regs->vendorspec, ESDHC_VENDORSPEC_VSELECT);
		if (!(esdhc_read32(&regs->vendorspec) &
		    ESDHC_VENDORSPEC_VSELECT))
			return 0;

		return -EAGAIN;
	case MMC_SIGNAL_VOLTAGE_180:
		if (CONFIG_IS_ENABLED(DM_REGULATOR) &&
		    !IS_ERR_OR_NULL(priv->vqmmc_dev)) {
			ret = regulator_set_value(priv->vqmmc_dev,
						  1800000);
			if (ret) {
				printf("Setting to 1.8V error");
				return -EIO;
			}
		}
		esdhc_setbits32(&regs->vendorspec, ESDHC_VENDORSPEC_VSELECT);
		/*
		 * some board like imx8mm-evk need about 18ms to switch
		 * the IO voltage from 3.3v to 1.8v, common code only
		 * delay 10ms, so need to delay extra time to make sure
		 * the IO voltage change to 1.8v.
		 */
		if (priv->signal_voltage_switch_extra_delay_ms)
			mdelay(priv->signal_voltage_switch_extra_delay_ms);
		if (esdhc_read32(&regs->vendorspec) & ESDHC_VENDORSPEC_VSELECT)
			return 0;

		return -EAGAIN;
	case MMC_SIGNAL_VOLTAGE_120:
		return -ENOTSUPP;
	default:
		return 0;
	}
}

static void esdhc_stop_tuning(struct mmc *mmc)
{
	struct mmc_cmd cmd;

	cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
	cmd.cmdarg = 0;
	cmd.resp_type = MMC_RSP_R1b;

	mmc_send_cmd(mmc, &cmd, NULL);
}

static int fsl_esdhc_execute_tuning(struct udevice *dev, uint32_t opcode)
{
	struct fsl_esdhc_plat *plat = dev_get_plat(dev);
	struct fsl_esdhc_priv *priv = dev_get_priv(dev);
	struct fsl_esdhc *regs = priv->esdhc_regs;
	struct mmc *mmc = &plat->mmc;
	u32 irqstaten = esdhc_read32(&regs->irqstaten);
	u32 irqsigen = esdhc_read32(&regs->irqsigen);
	int i, err, ret = -ETIMEDOUT;
	u32 val, mixctrl, tmp;

	/* clock tuning is not needed for upto 52MHz */
	if (mmc->clock <= 52000000)
		return 0;

	/* make sure the card clock keep on */
	esdhc_setbits32(&regs->vendorspec, VENDORSPEC_FRC_SDCLK_ON);

	/* This is readw/writew SDHCI_HOST_CONTROL2 when tuning */
	if (priv->flags & ESDHC_FLAG_STD_TUNING) {
		val = esdhc_read32(&regs->autoc12err);
		mixctrl = esdhc_read32(&regs->mixctrl);
		val &= ~MIX_CTRL_SMPCLK_SEL;
		mixctrl &= ~(MIX_CTRL_FBCLK_SEL | MIX_CTRL_AUTO_TUNE_EN);

		val |= MIX_CTRL_EXE_TUNE;
		mixctrl |= MIX_CTRL_FBCLK_SEL | MIX_CTRL_AUTO_TUNE_EN;

		esdhc_write32(&regs->autoc12err, val);
		esdhc_write32(&regs->mixctrl, mixctrl);
	}

	/* sdhci_writew(host, SDHCI_TRNS_READ, SDHCI_TRANSFER_MODE); */
	mixctrl = esdhc_read32(&regs->mixctrl);
	mixctrl = MIX_CTRL_DTDSEL_READ | (mixctrl & ~MIX_CTRL_SDHCI_MASK);
	esdhc_write32(&regs->mixctrl, mixctrl);

	esdhc_write32(&regs->irqstaten, IRQSTATEN_BRR);
	esdhc_write32(&regs->irqsigen, IRQSTATEN_BRR);

	/*
	 * Issue opcode repeatedly till Execute Tuning is set to 0 or the number
	 * of loops reaches 40 times.
	 */
	for (i = 0; i < MAX_TUNING_LOOP; i++) {
		u32 ctrl;

		if (opcode == MMC_CMD_SEND_TUNING_BLOCK_HS200) {
			if (mmc->bus_width == 8)
				esdhc_write32(&regs->blkattr, 0x7080);
			else if (mmc->bus_width == 4)
				esdhc_write32(&regs->blkattr, 0x7040);
		} else {
			esdhc_write32(&regs->blkattr, 0x7040);
		}

		/* sdhci_writew(host, SDHCI_TRNS_READ, SDHCI_TRANSFER_MODE) */
		val = esdhc_read32(&regs->mixctrl);
		val = MIX_CTRL_DTDSEL_READ | (val & ~MIX_CTRL_SDHCI_MASK);
		esdhc_write32(&regs->mixctrl, val);

		/* We are using STD tuning, no need to check return value */
		mmc_send_tuning(mmc, opcode);

		ctrl = esdhc_read32(&regs->autoc12err);
		if ((!(ctrl & MIX_CTRL_EXE_TUNE)) &&
		    (ctrl & MIX_CTRL_SMPCLK_SEL)) {
			ret = 0;
			break;
		}
	}

	esdhc_write32(&regs->irqstaten, irqstaten);
	esdhc_write32(&regs->irqsigen, irqsigen);

	esdhc_stop_tuning(mmc);

	/* change to default setting, let host control the card clock */
	esdhc_clrbits32(&regs->vendorspec, VENDORSPEC_FRC_SDCLK_ON);
	err = readx_poll_timeout(esdhc_read32, &regs->prsstat, tmp, tmp & PRSSTAT_SDOFF, 100);
	if (err)
		dev_warn(dev, "card clock not gate off as expect.\n");

	return ret;
}
#endif

static int esdhc_set_ios_common(struct fsl_esdhc_priv *priv, struct mmc *mmc)
{
	struct fsl_esdhc *regs = priv->esdhc_regs;
	int ret __maybe_unused;
	u32 clock;

#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING)
	/*
	 * call esdhc_set_timing() before update the clock rate,
	 * This is because current we support DDR and SDR mode,
	 * Once the DDR_EN bit is set, the card clock will be
	 * divide by 2 automatically. So need to do this before
	 * setting clock rate.
	 */
	if (priv->mode != mmc->selected_mode) {
		ret = esdhc_set_timing(mmc);
		if (ret) {
			printf("esdhc_set_timing error %d\n", ret);
			return ret;
		}
	}
#endif

	/* Set the clock speed */
	clock = mmc->clock;
	if (clock < mmc->cfg->f_min)
		clock = mmc->cfg->f_min;

	if (priv->clock != clock)
		set_sysctl(priv, mmc, clock);

	if (mmc->clk_disable) {
		if (IS_ENABLED(CONFIG_FSL_USDHC))
			esdhc_clrbits32(&regs->vendorspec, VENDORSPEC_CKEN);
		else
			esdhc_clrbits32(&regs->sysctl, SYSCTL_CKEN);
	} else {
		if (IS_ENABLED(CONFIG_FSL_USDHC))
			esdhc_setbits32(&regs->vendorspec, VENDORSPEC_PEREN |
					VENDORSPEC_CKEN);
		else
			esdhc_setbits32(&regs->sysctl, SYSCTL_PEREN | SYSCTL_CKEN);
	}

#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING)
	/*
	 * For HS400/HS400ES mode, make sure set the strobe dll in the
	 * target clock rate. So call esdhc_set_strobe_dll() after the
	 * clock updated.
	 */
	if (mmc->selected_mode == MMC_HS_400 || mmc->selected_mode == MMC_HS_400_ES)
		esdhc_set_strobe_dll(mmc);

	if (priv->signal_voltage != mmc->signal_voltage) {
		ret = esdhc_set_voltage(mmc);
		if (ret) {
			if (ret != -ENOTSUPP)
				printf("esdhc_set_voltage error %d\n", ret);
			return ret;
		}
	}
#endif

	/* Set the bus width */
	esdhc_clrbits32(&regs->proctl, PROCTL_DTW_4 | PROCTL_DTW_8);

	if (mmc->bus_width == 4)
		esdhc_setbits32(&regs->proctl, PROCTL_DTW_4);
	else if (mmc->bus_width == 8)
		esdhc_setbits32(&regs->proctl, PROCTL_DTW_8);

	return 0;
}

static int esdhc_init_common(struct fsl_esdhc_priv *priv, struct mmc *mmc)
{
	struct fsl_esdhc *regs = priv->esdhc_regs;
	ulong start;

	/* Reset the entire host controller */
	esdhc_setbits32(&regs->sysctl, SYSCTL_RSTA);

	/* Wait until the controller is available */
	start = get_timer(0);
	while ((esdhc_read32(&regs->sysctl) & SYSCTL_RSTA)) {
		if (get_timer(start) > 1000)
			return -ETIMEDOUT;
	}

	if (IS_ENABLED(CONFIG_FSL_USDHC)) {
		/* RSTA doesn't reset MMC_BOOT register, so manually reset it */
		esdhc_write32(&regs->mmcboot, 0x0);
		/* Reset MIX_CTRL and CLK_TUNE_CTRL_STATUS regs to 0 */
		esdhc_write32(&regs->mixctrl, 0x0);
		esdhc_write32(&regs->clktunectrlstatus, 0x0);

		/* Put VEND_SPEC to default value */
		if (priv->vs18_enable)
			esdhc_write32(&regs->vendorspec, VENDORSPEC_INIT |
				      ESDHC_VENDORSPEC_VSELECT);
		else
			esdhc_write32(&regs->vendorspec, VENDORSPEC_INIT);

		/* Disable DLL_CTRL delay line */
		esdhc_write32(&regs->dllctrl, 0x0);
	}

	if (IS_ENABLED(CONFIG_FSL_USDHC))
		esdhc_setbits32(&regs->vendorspec,
				VENDORSPEC_HCKEN | VENDORSPEC_IPGEN);
	else
		esdhc_setbits32(&regs->sysctl, SYSCTL_HCKEN | SYSCTL_IPGEN);

	/* Set the initial clock speed */
	set_sysctl(priv, mmc, 400000);

	/* Disable the BRR and BWR bits in IRQSTAT */
	esdhc_clrbits32(&regs->irqstaten, IRQSTATEN_BRR | IRQSTATEN_BWR);

	/* Put the PROCTL reg back to the default */
	if (IS_ENABLED(CONFIG_MCF5441x))
		esdhc_write32(&regs->proctl, PROCTL_INIT | PROCTL_D3CD);
	else
		esdhc_write32(&regs->proctl, PROCTL_INIT);

	/* Set timout to the maximum value */
	esdhc_clrsetbits32(&regs->sysctl, SYSCTL_TIMEOUT_MASK, 14 << 16);

	return 0;
}

static int esdhc_getcd_common(struct fsl_esdhc_priv *priv)
{
	struct fsl_esdhc *regs = priv->esdhc_regs;
	int timeout = 1000;

	if (IS_ENABLED(CONFIG_ESDHC_DETECT_QUIRK))
		return 1;

	if (CONFIG_IS_ENABLED(DM_MMC)) {
		if (priv->broken_cd)
			return 1;
#if CONFIG_IS_ENABLED(DM_GPIO)
		if (dm_gpio_is_valid(&priv->cd_gpio))
			return dm_gpio_get_value(&priv->cd_gpio);
#endif
	}

	while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_CINS) && --timeout)
		udelay(1000);

	return timeout > 0;
}

static int esdhc_wait_dat0_common(struct fsl_esdhc_priv *priv, int state,
				  int timeout_us)
{
	struct fsl_esdhc *regs = priv->esdhc_regs;
	int ret, err;
	u32 tmp;

	/* make sure the card clock keep on */
	esdhc_setbits32(&regs->vendorspec, VENDORSPEC_FRC_SDCLK_ON);

	ret = readx_poll_timeout(esdhc_read32, &regs->prsstat, tmp,
				!!(tmp & PRSSTAT_DAT0) == !!state,
				timeout_us);

	/* change to default setting, let host control the card clock */
	esdhc_clrbits32(&regs->vendorspec, VENDORSPEC_FRC_SDCLK_ON);

	err = readx_poll_timeout(esdhc_read32, &regs->prsstat, tmp, tmp & PRSSTAT_SDOFF, 100);
	if (err)
		pr_warn("card clock not gate off as expect.\n");

	return ret;
}

static int esdhc_reset(struct fsl_esdhc *regs)
{
	ulong start;

	/* reset the controller */
	esdhc_setbits32(&regs->sysctl, SYSCTL_RSTA);

	/* hardware clears the bit when it is done */
	start = get_timer(0);
	while ((esdhc_read32(&regs->sysctl) & SYSCTL_RSTA)) {
		if (get_timer(start) > 100) {
			printf("MMC/SD: Reset never completed.\n");
			return -ETIMEDOUT;
		}
	}

	return 0;
}

#if !CONFIG_IS_ENABLED(DM_MMC)
static int esdhc_getcd(struct mmc *mmc)
{
	struct fsl_esdhc_priv *priv = mmc->priv;

	return esdhc_getcd_common(priv);
}

static int esdhc_init(struct mmc *mmc)
{
	struct fsl_esdhc_priv *priv = mmc->priv;

	return esdhc_init_common(priv, mmc);
}

static int esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
			  struct mmc_data *data)
{
	struct fsl_esdhc_priv *priv = mmc->priv;

	return esdhc_send_cmd_common(priv, mmc, cmd, data);
}

static int esdhc_set_ios(struct mmc *mmc)
{
	struct fsl_esdhc_priv *priv = mmc->priv;

	return esdhc_set_ios_common(priv, mmc);
}

static int esdhc_wait_dat0(struct mmc *mmc, int state, int timeout_us)
{
	struct fsl_esdhc_priv *priv = mmc->priv;

	return esdhc_wait_dat0_common(priv, state, timeout_us);
}

static const struct mmc_ops esdhc_ops = {
	.getcd		= esdhc_getcd,
	.init		= esdhc_init,
	.send_cmd	= esdhc_send_cmd,
	.set_ios	= esdhc_set_ios,
	.wait_dat0	= esdhc_wait_dat0,
};
#endif

static int fsl_esdhc_init(struct fsl_esdhc_priv *priv,
			  struct fsl_esdhc_plat *plat)
{
	struct mmc_config *cfg;
	struct fsl_esdhc *regs;
	u32 caps;
	int ret;

	if (!priv)
		return -EINVAL;

	regs = priv->esdhc_regs;

	/* First reset the eSDHC controller */
	ret = esdhc_reset(regs);
	if (ret)
		return ret;

	/* ColdFire, using SDHC_DATA[3] for card detection */
	if (IS_ENABLED(CONFIG_MCF5441x))
		esdhc_write32(&regs->proctl, PROCTL_INIT | PROCTL_D3CD);

	if (IS_ENABLED(CONFIG_FSL_USDHC)) {
		esdhc_setbits32(&regs->vendorspec, VENDORSPEC_PEREN |
				VENDORSPEC_HCKEN | VENDORSPEC_IPGEN | VENDORSPEC_CKEN);
	} else {
		esdhc_setbits32(&regs->sysctl, SYSCTL_PEREN | SYSCTL_HCKEN
					| SYSCTL_IPGEN | SYSCTL_CKEN);
		/* Clearing tuning bits in case ROM has set it already */
		esdhc_write32(&regs->mixctrl, 0);
		esdhc_write32(&regs->autoc12err, 0);
		esdhc_write32(&regs->clktunectrlstatus, 0);
	}

	if (priv->vs18_enable)
		esdhc_setbits32(&regs->vendorspec, ESDHC_VENDORSPEC_VSELECT);

	esdhc_write32(&regs->irqstaten, SDHCI_IRQ_EN_BITS);
	cfg = &plat->cfg;
	if (!CONFIG_IS_ENABLED(DM_MMC))
		memset(cfg, '\0', sizeof(*cfg));

	caps = esdhc_read32(&regs->hostcapblt);

	/*
	 * MCF5441x RM declares in more points that sdhc clock speed must
	 * never exceed 25 Mhz. From this, the HS bit needs to be disabled
	 * from host capabilities.
	 */
	if (IS_ENABLED(CONFIG_MCF5441x))
		caps &= ~HOSTCAPBLT_HSS;

	if (IS_ENABLED(CONFIG_SYS_FSL_ERRATUM_ESDHC135))
		caps &= ~(HOSTCAPBLT_SRS | HOSTCAPBLT_VS18 | HOSTCAPBLT_VS30);

	if (IS_ENABLED(CONFIG_SYS_FSL_MMC_HAS_CAPBLT_VS33))
		caps |= HOSTCAPBLT_VS33;

	if (caps & HOSTCAPBLT_VS18)
		cfg->voltages |= MMC_VDD_165_195;
	if (caps & HOSTCAPBLT_VS30)
		cfg->voltages |= MMC_VDD_29_30 | MMC_VDD_30_31;
	if (caps & HOSTCAPBLT_VS33)
		cfg->voltages |= MMC_VDD_32_33 | MMC_VDD_33_34;

	cfg->name = "FSL_SDHC";

#if !CONFIG_IS_ENABLED(DM_MMC)
	cfg->ops = &esdhc_ops;
#endif

	if (IS_ENABLED(CONFIG_SYS_FSL_ESDHC_HAS_DDR_MODE))
		cfg->host_caps |= MMC_MODE_DDR_52MHz;

	if (caps & HOSTCAPBLT_HSS)
		cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;

	cfg->host_caps |= priv->caps;

	cfg->f_min = 400000;
	cfg->f_max = min(priv->sdhc_clk, (u32)200000000);

	cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;

	esdhc_write32(&regs->dllctrl, 0);
	if (priv->flags & ESDHC_FLAG_USDHC) {
		if (priv->flags & ESDHC_FLAG_STD_TUNING) {
			u32 val = esdhc_read32(&regs->tuning_ctrl);

			val |= ESDHC_STD_TUNING_EN;
			val &= ~ESDHC_TUNING_START_TAP_MASK;
			val |= priv->tuning_start_tap;
			val &= ~ESDHC_TUNING_STEP_MASK;
			val |= (priv->tuning_step) << ESDHC_TUNING_STEP_SHIFT;

			/* Disable the CMD CRC check for tuning, if not, need to
			 * add some delay after every tuning command, because
			 * hardware standard tuning logic will directly go to next
			 * step once it detect the CMD CRC error, will not wait for
			 * the card side to finally send out the tuning data, trigger
			 * the buffer read ready interrupt immediately. If usdhc send
			 * the next tuning command some eMMC card will stuck, can't
			 * response, block the tuning procedure or the first command
			 * after the whole tuning procedure always can't get any response.
			 */
			val |= ESDHC_TUNING_CMD_CRC_CHECK_DISABLE;
			esdhc_write32(&regs->tuning_ctrl, val);
		}

		/*
		 * UHS doesn't have explicit ESDHC flags, so if it's
		 * not supported, disable it in config.
		 */
		if (CONFIG_IS_ENABLED(MMC_UHS_SUPPORT))
			cfg->host_caps |= UHS_CAPS;

		if (CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)) {
			if (priv->flags & ESDHC_FLAG_HS200)
				cfg->host_caps |= MMC_CAP(MMC_HS_200);
		}

		if (CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)) {
			if (priv->flags & ESDHC_FLAG_HS400)
				cfg->host_caps |= MMC_CAP(MMC_HS_400);
		}

		if (CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT)) {
			if (priv->flags & ESDHC_FLAG_HS400_ES)
				cfg->host_caps |= MMC_CAP(MMC_HS_400_ES);
		}
	}
	return 0;
}

#if !CONFIG_IS_ENABLED(DM_MMC)
int fsl_esdhc_initialize(struct bd_info *bis, struct fsl_esdhc_cfg *cfg)
{
	struct fsl_esdhc_plat *plat;
	struct fsl_esdhc_priv *priv;
	struct mmc_config *mmc_cfg;
	struct mmc *mmc;
	int ret;

	if (!cfg)
		return -EINVAL;

	priv = calloc(sizeof(struct fsl_esdhc_priv), 1);
	if (!priv)
		return -ENOMEM;
	plat = calloc(sizeof(struct fsl_esdhc_plat), 1);
	if (!plat) {
		free(priv);
		return -ENOMEM;
	}

	priv->esdhc_regs = (struct fsl_esdhc *)(unsigned long)(cfg->esdhc_base);
	priv->sdhc_clk = cfg->sdhc_clk;
	priv->wp_enable  = cfg->wp_enable;

	mmc_cfg = &plat->cfg;

	switch (cfg->max_bus_width) {
	case 0: /* Not set in config; assume everything is supported */
	case 8:
		mmc_cfg->host_caps |= MMC_MODE_8BIT;
		fallthrough;
	case 4:
		mmc_cfg->host_caps |= MMC_MODE_4BIT;
		fallthrough;
	case 1:
		mmc_cfg->host_caps |= MMC_MODE_1BIT;
		break;
	default:
		printf("invalid max bus width %u\n", cfg->max_bus_width);
		return -EINVAL;
	}

	if (IS_ENABLED(CONFIG_ESDHC_DETECT_8_BIT_QUIRK))
		mmc_cfg->host_caps &= ~MMC_MODE_8BIT;

	ret = fsl_esdhc_init(priv, plat);
	if (ret) {
		debug("%s init failure\n", __func__);
		free(plat);
		free(priv);
		return ret;
	}

	mmc = mmc_create(&plat->cfg, priv);
	if (!mmc)
		return -EIO;

	priv->mmc = mmc;

	return 0;
}

int fsl_esdhc_mmc_init(struct bd_info *bis)
{
	struct fsl_esdhc_cfg *cfg;

	cfg = calloc(sizeof(struct fsl_esdhc_cfg), 1);
	cfg->esdhc_base = CFG_SYS_FSL_ESDHC_ADDR;
	cfg->sdhc_clk = gd->arch.sdhc_clk;
	return fsl_esdhc_initialize(bis, cfg);
}
#endif

#if CONFIG_IS_ENABLED(OF_LIBFDT)
__weak int esdhc_status_fixup(void *blob, const char *compat)
{
	if (IS_ENABLED(CONFIG_FSL_ESDHC_PIN_MUX) && !hwconfig("esdhc")) {
		do_fixup_by_compat(blob, compat, "status", "disabled",
				sizeof("disabled"), 1);
		return 1;
	}
	return 0;
}

void fdt_fixup_esdhc(void *blob, struct bd_info *bd)
{
	const char *compat = "fsl,esdhc";

	if (esdhc_status_fixup(blob, compat))
		return;

	do_fixup_by_compat_u32(blob, compat, "clock-frequency",
			       gd->arch.sdhc_clk, 1);
}
#endif

#if CONFIG_IS_ENABLED(DM_MMC)
#include <asm/arch/clock.h>
__weak void init_clk_usdhc(u32 index)
{
}

static int fsl_esdhc_of_to_plat(struct udevice *dev)
{
	struct fsl_esdhc_priv *priv = dev_get_priv(dev);
	struct udevice *vqmmc_dev;
	int ret;

	const void *fdt = gd->fdt_blob;
	int node = dev_of_offset(dev);
	fdt_addr_t addr;
	unsigned int val;

	if (!CONFIG_IS_ENABLED(OF_REAL))
		return 0;

	addr = dev_read_addr(dev);
	if (addr == FDT_ADDR_T_NONE)
		return -EINVAL;
	priv->esdhc_regs = (struct fsl_esdhc *)addr;
	priv->dev = dev;
	priv->mode = -1;

	val = fdtdec_get_int(fdt, node, "fsl,tuning-step", 1);
	priv->tuning_step = val;
	val = fdtdec_get_int(fdt, node, "fsl,tuning-start-tap",
			     ESDHC_TUNING_START_TAP_DEFAULT);
	priv->tuning_start_tap = val;
	val = fdtdec_get_int(fdt, node, "fsl,strobe-dll-delay-target",
			     ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_DEFAULT);
	priv->strobe_dll_delay_target = val;
	val = fdtdec_get_int(fdt, node, "fsl,signal-voltage-switch-extra-delay-ms", 0);
	priv->signal_voltage_switch_extra_delay_ms = val;

	if (dev_read_bool(dev, "broken-cd"))
		priv->broken_cd = 1;

	if (dev_read_prop(dev, "fsl,wp-controller", NULL)) {
		priv->wp_enable = 1;
	} else {
		priv->wp_enable = 0;
	}

#if CONFIG_IS_ENABLED(DM_GPIO)
	gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio,
			     GPIOD_IS_IN);
	gpio_request_by_name(dev, "wp-gpios", 0, &priv->wp_gpio,
			     GPIOD_IS_IN);
#endif

	priv->vs18_enable = 0;

	if (!CONFIG_IS_ENABLED(DM_REGULATOR))
		return 0;

	/*
	 * If emmc I/O has a fixed voltage at 1.8V, this must be provided,
	 * otherwise, emmc will work abnormally.
	 */
	ret = device_get_supply_regulator(dev, "vqmmc-supply", &vqmmc_dev);
	if (ret) {
		dev_dbg(dev, "no vqmmc-supply\n");
	} else {
		priv->vqmmc_dev = vqmmc_dev;
		ret = regulator_set_enable(vqmmc_dev, true);
		if (ret) {
			dev_err(dev, "fail to enable vqmmc-supply\n");
			return ret;
		}

		if (regulator_get_value(vqmmc_dev) == 1800000)
			priv->vs18_enable = 1;
	}
	return 0;
}

static int fsl_esdhc_probe(struct udevice *dev)
{
	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
	struct fsl_esdhc_plat *plat = dev_get_plat(dev);
	struct fsl_esdhc_priv *priv = dev_get_priv(dev);
	struct esdhc_soc_data *data =
		(struct esdhc_soc_data *)dev_get_driver_data(dev);
	struct mmc *mmc;
	int ret;

#if CONFIG_IS_ENABLED(OF_PLATDATA)
	struct dtd_fsl_esdhc *dtplat = &plat->dtplat;

	priv->esdhc_regs = map_sysmem(dtplat->reg[0], dtplat->reg[1]);

	if (dtplat->non_removable)
		plat->cfg.host_caps |= MMC_CAP_NONREMOVABLE;
	else
		plat->cfg.host_caps &= ~MMC_CAP_NONREMOVABLE;

	if (CONFIG_IS_ENABLED(DM_GPIO) && !dtplat->non_removable) {
		struct udevice *gpiodev;

		ret = device_get_by_ofplat_idx(dtplat->cd_gpios->idx, &gpiodev);
		if (ret)
			return ret;

		ret = gpio_dev_request_index(gpiodev, gpiodev->name, "cd-gpios",
					     dtplat->cd_gpios->arg[0], GPIOD_IS_IN,
					     dtplat->cd_gpios->arg[1], &priv->cd_gpio);

		if (ret)
			return ret;
	}
#endif

	if (data)
		priv->flags = data->flags;

	/*
	 * TODO:
	 * Because lack of clk driver, if SDHC clk is not enabled,
	 * need to enable it first before this driver is invoked.
	 *
	 * we use MXC_ESDHC_CLK to get clk freq.
	 * If one would like to make this function work,
	 * the aliases should be provided in dts as this:
	 *
	 *  aliases {
	 *	mmc0 = &usdhc1;
	 *	mmc1 = &usdhc2;
	 *	mmc2 = &usdhc3;
	 *	mmc3 = &usdhc4;
	 *	};
	 * Then if your board only supports mmc2 and mmc3, but we can
	 * correctly get the seq as 2 and 3, then let mxc_get_clock
	 * work as expected.
	 */

#if CONFIG_IS_ENABLED(CLK)
	/* Assigned clock already set clock */
	ret = clk_get_by_name(dev, "per", &priv->per_clk);
	if (ret) {
		printf("Failed to get per_clk\n");
		return ret;
	}
	ret = clk_enable(&priv->per_clk);
	if (ret) {
		printf("Failed to enable per_clk\n");
		return ret;
	}

	priv->sdhc_clk = clk_get_rate(&priv->per_clk);
#else
	init_clk_usdhc(dev_seq(dev));

	priv->sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK + dev_seq(dev));
	if (priv->sdhc_clk <= 0) {
		dev_err(dev, "Unable to get clk for %s\n", dev->name);
		return -EINVAL;
	}
#endif

	ret = fsl_esdhc_init(priv, plat);
	if (ret) {
		dev_err(dev, "fsl_esdhc_init failure\n");
		return ret;
	}

	if (CONFIG_IS_ENABLED(OF_REAL)) {
		ret = mmc_of_parse(dev, &plat->cfg);
		if (ret)
			return ret;
	}

	mmc = &plat->mmc;
	mmc->cfg = &plat->cfg;
	mmc->dev = dev;

	upriv->mmc = mmc;

	return esdhc_init_common(priv, mmc);
}

static int fsl_esdhc_get_cd(struct udevice *dev)
{
	struct fsl_esdhc_plat *plat = dev_get_plat(dev);
	struct fsl_esdhc_priv *priv = dev_get_priv(dev);

	if (plat->cfg.host_caps & MMC_CAP_NONREMOVABLE)
		return 1;

	return esdhc_getcd_common(priv);
}

static int fsl_esdhc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
			      struct mmc_data *data)
{
	struct fsl_esdhc_plat *plat = dev_get_plat(dev);
	struct fsl_esdhc_priv *priv = dev_get_priv(dev);

	return esdhc_send_cmd_common(priv, &plat->mmc, cmd, data);
}

static int fsl_esdhc_set_ios(struct udevice *dev)
{
	struct fsl_esdhc_plat *plat = dev_get_plat(dev);
	struct fsl_esdhc_priv *priv = dev_get_priv(dev);

	return esdhc_set_ios_common(priv, &plat->mmc);
}

static int __maybe_unused fsl_esdhc_set_enhanced_strobe(struct udevice *dev)
{
	struct fsl_esdhc_priv *priv = dev_get_priv(dev);
	struct fsl_esdhc *regs = priv->esdhc_regs;
	u32 m;

	m = esdhc_read32(&regs->mixctrl);
	m |= MIX_CTRL_HS400_ES;
	esdhc_write32(&regs->mixctrl, m);

	return 0;
}

static int fsl_esdhc_wait_dat0(struct udevice *dev, int state,
				int timeout_us)
{
	struct fsl_esdhc_priv *priv = dev_get_priv(dev);

	return esdhc_wait_dat0_common(priv, state, timeout_us);
}

static const struct dm_mmc_ops fsl_esdhc_ops = {
	.get_cd		= fsl_esdhc_get_cd,
	.send_cmd	= fsl_esdhc_send_cmd,
	.set_ios	= fsl_esdhc_set_ios,
#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING)
	.execute_tuning	= fsl_esdhc_execute_tuning,
#endif
#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT)
	.set_enhanced_strobe = fsl_esdhc_set_enhanced_strobe,
#endif
	.wait_dat0 = fsl_esdhc_wait_dat0,
};

static struct esdhc_soc_data usdhc_imx7d_data = {
	.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
			| ESDHC_FLAG_HS400,
};

static struct esdhc_soc_data usdhc_imx7ulp_data = {
	.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
			| ESDHC_FLAG_HS400,
};

static struct esdhc_soc_data usdhc_imx8qm_data = {
	.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING |
		ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 |
		ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES,
};

static const struct udevice_id fsl_esdhc_ids[] = {
	{ .compatible = "fsl,imx51-esdhc", },
	{ .compatible = "fsl,imx53-esdhc", },
	{ .compatible = "fsl,imx6ul-usdhc", },
	{ .compatible = "fsl,imx6sx-usdhc", },
	{ .compatible = "fsl,imx6sl-usdhc", },
	{ .compatible = "fsl,imx6q-usdhc", },
	{ .compatible = "fsl,imx7d-usdhc", .data = (ulong)&usdhc_imx7d_data,},
	{ .compatible = "fsl,imx7ulp-usdhc", .data = (ulong)&usdhc_imx7ulp_data,},
	{ .compatible = "fsl,imx8qm-usdhc", .data = (ulong)&usdhc_imx8qm_data,},
	{ .compatible = "fsl,imx8mm-usdhc", .data = (ulong)&usdhc_imx8qm_data,},
	{ .compatible = "fsl,imx8mn-usdhc", .data = (ulong)&usdhc_imx8qm_data,},
	{ .compatible = "fsl,imx8mp-usdhc", .data = (ulong)&usdhc_imx8qm_data,},
	{ .compatible = "fsl,imx8mq-usdhc", .data = (ulong)&usdhc_imx8qm_data,},
	{ .compatible = "fsl,imxrt-usdhc", },
	{ .compatible = "fsl,esdhc", },
	{ /* sentinel */ }
};

static int fsl_esdhc_bind(struct udevice *dev)
{
	struct fsl_esdhc_plat *plat = dev_get_plat(dev);

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

U_BOOT_DRIVER(fsl_esdhc) = {
	.name	= "fsl_esdhc",
	.id	= UCLASS_MMC,
	.of_match = fsl_esdhc_ids,
	.of_to_plat = fsl_esdhc_of_to_plat,
	.ops	= &fsl_esdhc_ops,
	.bind	= fsl_esdhc_bind,
	.probe	= fsl_esdhc_probe,
	.plat_auto	= sizeof(struct fsl_esdhc_plat),
	.priv_auto	= sizeof(struct fsl_esdhc_priv),
};

DM_DRIVER_ALIAS(fsl_esdhc, fsl_imx6q_usdhc)
#endif
