// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2016 Socionext Inc.
 *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 */

#include <asm/dma-mapping.h>
#include <common.h>
#include <clk.h>
#include <cpu_func.h>
#include <fdtdec.h>
#include <mmc.h>
#include <dm.h>
#include <dm/device_compat.h>
#include <dm/pinctrl.h>
#include <linux/compat.h>
#include <linux/dma-direction.h>
#include <linux/io.h>
#include <linux/sizes.h>
#include <power/regulator.h>
#include <asm/unaligned.h>

#include "tmio-common.h"

DECLARE_GLOBAL_DATA_PTR;

static u64 tmio_sd_readq(struct tmio_sd_priv *priv, unsigned int reg)
{
	return readq(priv->regbase + (reg << 1));
}

static void tmio_sd_writeq(struct tmio_sd_priv *priv,
			       u64 val, unsigned int reg)
{
	writeq(val, priv->regbase + (reg << 1));
}

static u16 tmio_sd_readw(struct tmio_sd_priv *priv, unsigned int reg)
{
	return readw(priv->regbase + (reg >> 1));
}

static void tmio_sd_writew(struct tmio_sd_priv *priv,
			       u16 val, unsigned int reg)
{
	writew(val, priv->regbase + (reg >> 1));
}

u32 tmio_sd_readl(struct tmio_sd_priv *priv, unsigned int reg)
{
	u32 val;

	if (priv->caps & TMIO_SD_CAP_64BIT)
		return readl(priv->regbase + (reg << 1));
	else if (priv->caps & TMIO_SD_CAP_16BIT) {
		val = readw(priv->regbase + (reg >> 1)) & 0xffff;
		if ((reg == TMIO_SD_RSP10) || (reg == TMIO_SD_RSP32) ||
		    (reg == TMIO_SD_RSP54) || (reg == TMIO_SD_RSP76)) {
			val |= readw(priv->regbase + (reg >> 1) + 2) << 16;
		}
		return val;
	} else
		return readl(priv->regbase + reg);
}

void tmio_sd_writel(struct tmio_sd_priv *priv,
			       u32 val, unsigned int reg)
{
	if (priv->caps & TMIO_SD_CAP_64BIT)
		writel(val, priv->regbase + (reg << 1));
	else if (priv->caps & TMIO_SD_CAP_16BIT) {
		writew(val & 0xffff, priv->regbase + (reg >> 1));
		if (reg == TMIO_SD_INFO1 || reg == TMIO_SD_INFO1_MASK ||
		    reg == TMIO_SD_INFO2 || reg == TMIO_SD_INFO2_MASK ||
		    reg == TMIO_SD_ARG)
			writew(val >> 16, priv->regbase + (reg >> 1) + 2);
	} else
		writel(val, priv->regbase + reg);
}

static int tmio_sd_check_error(struct udevice *dev, struct mmc_cmd *cmd)
{
	struct tmio_sd_priv *priv = dev_get_priv(dev);
	u32 info2 = tmio_sd_readl(priv, TMIO_SD_INFO2);

	if (info2 & TMIO_SD_INFO2_ERR_RTO) {
		/*
		 * TIMEOUT must be returned for unsupported command.  Do not
		 * display error log since this might be a part of sequence to
		 * distinguish between SD and MMC.
		 */
		return -ETIMEDOUT;
	}

	if (info2 & TMIO_SD_INFO2_ERR_TO) {
		dev_err(dev, "timeout error\n");
		return -ETIMEDOUT;
	}

	if (info2 & (TMIO_SD_INFO2_ERR_END | TMIO_SD_INFO2_ERR_CRC |
		     TMIO_SD_INFO2_ERR_IDX)) {
		if ((cmd->cmdidx != MMC_CMD_SEND_TUNING_BLOCK) &&
		    (cmd->cmdidx != MMC_CMD_SEND_TUNING_BLOCK_HS200))
			dev_err(dev, "communication out of sync\n");
		return -EILSEQ;
	}

	if (info2 & (TMIO_SD_INFO2_ERR_ILA | TMIO_SD_INFO2_ERR_ILR |
		     TMIO_SD_INFO2_ERR_ILW)) {
		dev_err(dev, "illegal access\n");
		return -EIO;
	}

	return 0;
}

static int tmio_sd_wait_for_irq(struct udevice *dev, struct mmc_cmd *cmd,
				unsigned int reg, u32 flag)
{
	struct tmio_sd_priv *priv = dev_get_priv(dev);
	long wait = 1000000;
	int ret;

	while (!(tmio_sd_readl(priv, reg) & flag)) {
		if (wait-- < 0) {
			dev_err(dev, "timeout\n");
			return -ETIMEDOUT;
		}

		ret = tmio_sd_check_error(dev, cmd);
		if (ret)
			return ret;

		udelay(1);
	}

	return 0;
}

#define tmio_pio_read_fifo(__width, __suffix)				\
static void tmio_pio_read_fifo_##__width(struct tmio_sd_priv *priv,	\
					  char *pbuf, uint blksz)	\
{									\
	u##__width *buf = (u##__width *)pbuf;				\
	int i;								\
									\
	if (likely(IS_ALIGNED((uintptr_t)buf, ((__width) / 8)))) {	\
		for (i = 0; i < blksz / ((__width) / 8); i++) {		\
			*buf++ = tmio_sd_read##__suffix(priv,		\
							 TMIO_SD_BUF);	\
		}							\
	} else {							\
		for (i = 0; i < blksz / ((__width) / 8); i++) {		\
			u##__width data;				\
			data = tmio_sd_read##__suffix(priv,		\
						       TMIO_SD_BUF);	\
			put_unaligned(data, buf++);			\
		}							\
	}								\
}

tmio_pio_read_fifo(64, q)
tmio_pio_read_fifo(32, l)
tmio_pio_read_fifo(16, w)

static int tmio_sd_pio_read_one_block(struct udevice *dev, struct mmc_cmd *cmd,
				      char *pbuf, uint blocksize)
{
	struct tmio_sd_priv *priv = dev_get_priv(dev);
	int ret;

	/* wait until the buffer is filled with data */
	ret = tmio_sd_wait_for_irq(dev, cmd, TMIO_SD_INFO2,
				   TMIO_SD_INFO2_BRE);
	if (ret)
		return ret;

	/*
	 * Clear the status flag _before_ read the buffer out because
	 * TMIO_SD_INFO2_BRE is edge-triggered, not level-triggered.
	 */
	tmio_sd_writel(priv, 0, TMIO_SD_INFO2);

	if (priv->caps & TMIO_SD_CAP_64BIT)
		tmio_pio_read_fifo_64(priv, pbuf, blocksize);
	else if (priv->caps & TMIO_SD_CAP_16BIT)
		tmio_pio_read_fifo_16(priv, pbuf, blocksize);
	else
		tmio_pio_read_fifo_32(priv, pbuf, blocksize);

	return 0;
}

#define tmio_pio_write_fifo(__width, __suffix)				\
static void tmio_pio_write_fifo_##__width(struct tmio_sd_priv *priv,	\
					   const char *pbuf, uint blksz)\
{									\
	const u##__width *buf = (const u##__width *)pbuf;		\
	int i;								\
									\
	if (likely(IS_ALIGNED((uintptr_t)buf, ((__width) / 8)))) {	\
		for (i = 0; i < blksz / ((__width) / 8); i++) {		\
			tmio_sd_write##__suffix(priv, *buf++,		\
						 TMIO_SD_BUF);		\
		}							\
	} else {							\
		for (i = 0; i < blksz / ((__width) / 8); i++) {		\
			u##__width data = get_unaligned(buf++);		\
			tmio_sd_write##__suffix(priv, data,		\
						 TMIO_SD_BUF);		\
		}							\
	}								\
}

tmio_pio_write_fifo(64, q)
tmio_pio_write_fifo(32, l)
tmio_pio_write_fifo(16, w)

static int tmio_sd_pio_write_one_block(struct udevice *dev, struct mmc_cmd *cmd,
					   const char *pbuf, uint blocksize)
{
	struct tmio_sd_priv *priv = dev_get_priv(dev);
	int ret;

	/* wait until the buffer becomes empty */
	ret = tmio_sd_wait_for_irq(dev, cmd, TMIO_SD_INFO2,
				   TMIO_SD_INFO2_BWE);
	if (ret)
		return ret;

	tmio_sd_writel(priv, 0, TMIO_SD_INFO2);

	if (priv->caps & TMIO_SD_CAP_64BIT)
		tmio_pio_write_fifo_64(priv, pbuf, blocksize);
	else if (priv->caps & TMIO_SD_CAP_16BIT)
		tmio_pio_write_fifo_16(priv, pbuf, blocksize);
	else
		tmio_pio_write_fifo_32(priv, pbuf, blocksize);

	return 0;
}

static int tmio_sd_pio_xfer(struct udevice *dev, struct mmc_cmd *cmd,
			    struct mmc_data *data)
{
	const char *src = data->src;
	char *dest = data->dest;
	int i, ret;

	for (i = 0; i < data->blocks; i++) {
		if (data->flags & MMC_DATA_READ)
			ret = tmio_sd_pio_read_one_block(dev, cmd, dest,
							     data->blocksize);
		else
			ret = tmio_sd_pio_write_one_block(dev, cmd, src,
							      data->blocksize);
		if (ret)
			return ret;

		if (data->flags & MMC_DATA_READ)
			dest += data->blocksize;
		else
			src += data->blocksize;
	}

	return 0;
}

static void tmio_sd_dma_start(struct tmio_sd_priv *priv,
				  dma_addr_t dma_addr)
{
	u32 tmp;

	tmio_sd_writel(priv, 0, TMIO_SD_DMA_INFO1);
	tmio_sd_writel(priv, 0, TMIO_SD_DMA_INFO2);

	/* enable DMA */
	tmp = tmio_sd_readl(priv, TMIO_SD_EXTMODE);
	tmp |= TMIO_SD_EXTMODE_DMA_EN;
	tmio_sd_writel(priv, tmp, TMIO_SD_EXTMODE);

	tmio_sd_writel(priv, dma_addr & U32_MAX, TMIO_SD_DMA_ADDR_L);

	/* suppress the warning "right shift count >= width of type" */
	dma_addr >>= min_t(int, 32, 8 * sizeof(dma_addr));

	tmio_sd_writel(priv, dma_addr & U32_MAX, TMIO_SD_DMA_ADDR_H);

	tmio_sd_writel(priv, TMIO_SD_DMA_CTL_START, TMIO_SD_DMA_CTL);
}

static int tmio_sd_dma_wait_for_irq(struct udevice *dev, u32 flag,
					unsigned int blocks)
{
	struct tmio_sd_priv *priv = dev_get_priv(dev);
	long wait = 1000000 + 10 * blocks;

	while (!(tmio_sd_readl(priv, TMIO_SD_DMA_INFO1) & flag)) {
		if (wait-- < 0) {
			dev_err(dev, "timeout during DMA\n");
			return -ETIMEDOUT;
		}

		udelay(10);
	}

	if (tmio_sd_readl(priv, TMIO_SD_DMA_INFO2)) {
		dev_err(dev, "error during DMA\n");
		return -EIO;
	}

	return 0;
}

static int tmio_sd_dma_xfer(struct udevice *dev, struct mmc_data *data)
{
	struct tmio_sd_priv *priv = dev_get_priv(dev);
	size_t len = data->blocks * data->blocksize;
	void *buf;
	enum dma_data_direction dir;
	dma_addr_t dma_addr;
	u32 poll_flag, tmp;
	int ret;

	tmp = tmio_sd_readl(priv, TMIO_SD_DMA_MODE);

	if (data->flags & MMC_DATA_READ) {
		buf = data->dest;
		dir = DMA_FROM_DEVICE;
		/*
		 * The DMA READ completion flag position differs on Socionext
		 * and Renesas SoCs. It is bit 20 on Socionext SoCs and using
		 * bit 17 is a hardware bug and forbidden. It is either bit 17
		 * or bit 20 on Renesas SoCs, depending on SoC.
		 */
		poll_flag = priv->read_poll_flag;
		tmp |= TMIO_SD_DMA_MODE_DIR_RD;
	} else {
		buf = (void *)data->src;
		dir = DMA_TO_DEVICE;
		poll_flag = TMIO_SD_DMA_INFO1_END_WR;
		tmp &= ~TMIO_SD_DMA_MODE_DIR_RD;
	}

	tmio_sd_writel(priv, tmp, TMIO_SD_DMA_MODE);

	dma_addr = dma_map_single(buf, len, dir);

	tmio_sd_dma_start(priv, dma_addr);

	ret = tmio_sd_dma_wait_for_irq(dev, poll_flag, data->blocks);

	if (poll_flag == TMIO_SD_DMA_INFO1_END_RD)
		udelay(1);

	dma_unmap_single(buf, len, dir);

	return ret;
}

/* check if the address is DMA'able */
static bool tmio_sd_addr_is_dmaable(const char *src)
{
	uintptr_t addr = (uintptr_t)src;

	if (!IS_ALIGNED(addr, TMIO_SD_DMA_MINALIGN))
		return false;

#if defined(CONFIG_RCAR_GEN3)
	/* Gen3 DMA has 32bit limit */
	if (addr >> 32)
		return false;
#endif

#if defined(CONFIG_ARCH_UNIPHIER) && !defined(CONFIG_ARM64) && \
	defined(CONFIG_SPL_BUILD)
	/*
	 * For UniPhier ARMv7 SoCs, the stack is allocated in the locked ways
	 * of L2, which is unreachable from the DMA engine.
	 */
	if (addr < CONFIG_SPL_STACK)
		return false;
#endif

	return true;
}

int tmio_sd_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
		      struct mmc_data *data)
{
	struct tmio_sd_priv *priv = dev_get_priv(dev);
	int ret;
	u32 tmp;

	if (tmio_sd_readl(priv, TMIO_SD_INFO2) & TMIO_SD_INFO2_CBSY) {
		dev_err(dev, "command busy\n");
		return -EBUSY;
	}

	/* clear all status flags */
	tmio_sd_writel(priv, 0, TMIO_SD_INFO1);
	tmio_sd_writel(priv, 0, TMIO_SD_INFO2);

	/* disable DMA once */
	tmp = tmio_sd_readl(priv, TMIO_SD_EXTMODE);
	tmp &= ~TMIO_SD_EXTMODE_DMA_EN;
	tmio_sd_writel(priv, tmp, TMIO_SD_EXTMODE);

	tmio_sd_writel(priv, cmd->cmdarg, TMIO_SD_ARG);

	tmp = cmd->cmdidx;

	if (data) {
		tmio_sd_writel(priv, data->blocksize, TMIO_SD_SIZE);
		tmio_sd_writel(priv, data->blocks, TMIO_SD_SECCNT);

		/* Do not send CMD12 automatically */
		tmp |= TMIO_SD_CMD_NOSTOP | TMIO_SD_CMD_DATA;

		if (data->blocks > 1)
			tmp |= TMIO_SD_CMD_MULTI;

		if (data->flags & MMC_DATA_READ)
			tmp |= TMIO_SD_CMD_RD;
	}

	/*
	 * Do not use the response type auto-detection on this hardware.
	 * CMD8, for example, has different response types on SD and eMMC,
	 * while this controller always assumes the response type for SD.
	 * Set the response type manually.
	 */
	switch (cmd->resp_type) {
	case MMC_RSP_NONE:
		tmp |= TMIO_SD_CMD_RSP_NONE;
		break;
	case MMC_RSP_R1:
		tmp |= TMIO_SD_CMD_RSP_R1;
		break;
	case MMC_RSP_R1b:
		tmp |= TMIO_SD_CMD_RSP_R1B;
		break;
	case MMC_RSP_R2:
		tmp |= TMIO_SD_CMD_RSP_R2;
		break;
	case MMC_RSP_R3:
		tmp |= TMIO_SD_CMD_RSP_R3;
		break;
	default:
		dev_err(dev, "unknown response type\n");
		return -EINVAL;
	}

	dev_dbg(dev, "sending CMD%d (SD_CMD=%08x, SD_ARG=%08x)\n",
		cmd->cmdidx, tmp, cmd->cmdarg);
	tmio_sd_writel(priv, tmp, TMIO_SD_CMD);

	ret = tmio_sd_wait_for_irq(dev, cmd, TMIO_SD_INFO1,
				   TMIO_SD_INFO1_RSP);
	if (ret)
		return ret;

	if (cmd->resp_type & MMC_RSP_136) {
		u32 rsp_127_104 = tmio_sd_readl(priv, TMIO_SD_RSP76);
		u32 rsp_103_72 = tmio_sd_readl(priv, TMIO_SD_RSP54);
		u32 rsp_71_40 = tmio_sd_readl(priv, TMIO_SD_RSP32);
		u32 rsp_39_8 = tmio_sd_readl(priv, TMIO_SD_RSP10);

		cmd->response[0] = ((rsp_127_104 & 0x00ffffff) << 8) |
				   ((rsp_103_72  & 0xff000000) >> 24);
		cmd->response[1] = ((rsp_103_72  & 0x00ffffff) << 8) |
				   ((rsp_71_40   & 0xff000000) >> 24);
		cmd->response[2] = ((rsp_71_40   & 0x00ffffff) << 8) |
				   ((rsp_39_8    & 0xff000000) >> 24);
		cmd->response[3] = (rsp_39_8     & 0xffffff)   << 8;
	} else {
		/* bit 39-8 */
		cmd->response[0] = tmio_sd_readl(priv, TMIO_SD_RSP10);
	}

	if (data) {
		/* use DMA if the HW supports it and the buffer is aligned */
		if (priv->caps & TMIO_SD_CAP_DMA_INTERNAL &&
		    tmio_sd_addr_is_dmaable(data->src))
			ret = tmio_sd_dma_xfer(dev, data);
		else
			ret = tmio_sd_pio_xfer(dev, cmd, data);
		if (ret)
			return ret;

		ret = tmio_sd_wait_for_irq(dev, cmd, TMIO_SD_INFO1,
					   TMIO_SD_INFO1_CMP);
		if (ret)
			return ret;
	}

	return tmio_sd_wait_for_irq(dev, cmd, TMIO_SD_INFO2,
				    TMIO_SD_INFO2_SCLKDIVEN);
}

static int tmio_sd_set_bus_width(struct tmio_sd_priv *priv,
				     struct mmc *mmc)
{
	u32 val, tmp;

	switch (mmc->bus_width) {
	case 0:
	case 1:
		val = TMIO_SD_OPTION_WIDTH_1;
		break;
	case 4:
		val = TMIO_SD_OPTION_WIDTH_4;
		break;
	case 8:
		val = TMIO_SD_OPTION_WIDTH_8;
		break;
	default:
		return -EINVAL;
	}

	tmp = tmio_sd_readl(priv, TMIO_SD_OPTION);
	tmp &= ~TMIO_SD_OPTION_WIDTH_MASK;
	tmp |= val;
	tmio_sd_writel(priv, tmp, TMIO_SD_OPTION);

	return 0;
}

static void tmio_sd_set_ddr_mode(struct tmio_sd_priv *priv,
				     struct mmc *mmc)
{
	u32 tmp;

	tmp = tmio_sd_readl(priv, TMIO_SD_IF_MODE);
	if (mmc->ddr_mode)
		tmp |= TMIO_SD_IF_MODE_DDR;
	else
		tmp &= ~TMIO_SD_IF_MODE_DDR;
	tmio_sd_writel(priv, tmp, TMIO_SD_IF_MODE);
}

static ulong tmio_sd_clk_get_rate(struct tmio_sd_priv *priv)
{
	return priv->clk_get_rate(priv);
}

static void tmio_sd_set_clk_rate(struct tmio_sd_priv *priv, struct mmc *mmc)
{
	unsigned int divisor;
	u32 tmp, val = 0;
	ulong mclk;

	if (mmc->clock) {
		mclk = tmio_sd_clk_get_rate(priv);

		divisor = DIV_ROUND_UP(mclk, mmc->clock);

		/* Do not set divider to 0xff in DDR mode */
		if (mmc->ddr_mode && (divisor == 1))
			divisor = 2;

		if (divisor <= 1)
			val = (priv->caps & TMIO_SD_CAP_RCAR) ?
			      TMIO_SD_CLKCTL_RCAR_DIV1 : TMIO_SD_CLKCTL_DIV1;
		else if (divisor <= 2)
			val = TMIO_SD_CLKCTL_DIV2;
		else if (divisor <= 4)
			val = TMIO_SD_CLKCTL_DIV4;
		else if (divisor <= 8)
			val = TMIO_SD_CLKCTL_DIV8;
		else if (divisor <= 16)
			val = TMIO_SD_CLKCTL_DIV16;
		else if (divisor <= 32)
			val = TMIO_SD_CLKCTL_DIV32;
		else if (divisor <= 64)
			val = TMIO_SD_CLKCTL_DIV64;
		else if (divisor <= 128)
			val = TMIO_SD_CLKCTL_DIV128;
		else if (divisor <= 256)
			val = TMIO_SD_CLKCTL_DIV256;
		else if (divisor <= 512 || !(priv->caps & TMIO_SD_CAP_DIV1024))
			val = TMIO_SD_CLKCTL_DIV512;
		else
			val = TMIO_SD_CLKCTL_DIV1024;
	}

	tmp = tmio_sd_readl(priv, TMIO_SD_CLKCTL);
	if (mmc->clock &&
	    !((tmp & TMIO_SD_CLKCTL_SCLKEN) &&
	      ((tmp & TMIO_SD_CLKCTL_DIV_MASK) == val))) {
		/*
		 * Stop the clock before changing its rate
		 * to avoid a glitch signal
		 */
		tmp &= ~TMIO_SD_CLKCTL_SCLKEN;
		tmio_sd_writel(priv, tmp, TMIO_SD_CLKCTL);

		/* Change the clock rate. */
		tmp &= ~TMIO_SD_CLKCTL_DIV_MASK;
		tmp |= val;
	}

	/* Enable or Disable the clock */
	if (mmc->clk_disable) {
		tmp |= TMIO_SD_CLKCTL_OFFEN;
		tmp &= ~TMIO_SD_CLKCTL_SCLKEN;
	} else {
		tmp &= ~TMIO_SD_CLKCTL_OFFEN;
		tmp |= TMIO_SD_CLKCTL_SCLKEN;
	}

	tmio_sd_writel(priv, tmp, TMIO_SD_CLKCTL);

	udelay(1000);
}

static void tmio_sd_set_pins(struct udevice *dev)
{
	__maybe_unused struct mmc *mmc = mmc_get_mmc_dev(dev);

#ifdef CONFIG_DM_REGULATOR
	struct tmio_sd_priv *priv = dev_get_priv(dev);

	if (priv->vqmmc_dev) {
		if (mmc->signal_voltage == MMC_SIGNAL_VOLTAGE_180)
			regulator_set_value(priv->vqmmc_dev, 1800000);
		else
			regulator_set_value(priv->vqmmc_dev, 3300000);
		regulator_set_enable(priv->vqmmc_dev, true);
	}
#endif

#ifdef CONFIG_PINCTRL
	if (mmc->signal_voltage == MMC_SIGNAL_VOLTAGE_180)
		pinctrl_select_state(dev, "state_uhs");
	else
		pinctrl_select_state(dev, "default");
#endif
}

int tmio_sd_set_ios(struct udevice *dev)
{
	struct tmio_sd_priv *priv = dev_get_priv(dev);
	struct mmc *mmc = mmc_get_mmc_dev(dev);
	int ret;

	dev_dbg(dev, "clock %uHz, DDRmode %d, width %u\n",
		mmc->clock, mmc->ddr_mode, mmc->bus_width);

	tmio_sd_set_clk_rate(priv, mmc);
	ret = tmio_sd_set_bus_width(priv, mmc);
	if (ret)
		return ret;
	tmio_sd_set_ddr_mode(priv, mmc);
	tmio_sd_set_pins(dev);

	return 0;
}

int tmio_sd_get_cd(struct udevice *dev)
{
	struct tmio_sd_priv *priv = dev_get_priv(dev);

	if (priv->caps & TMIO_SD_CAP_NONREMOVABLE)
		return 1;

	return !!(tmio_sd_readl(priv, TMIO_SD_INFO1) &
		  TMIO_SD_INFO1_CD);
}

static void tmio_sd_host_init(struct tmio_sd_priv *priv)
{
	u32 tmp;

	/* soft reset of the host */
	tmp = tmio_sd_readl(priv, TMIO_SD_SOFT_RST);
	tmp &= ~TMIO_SD_SOFT_RST_RSTX;
	tmio_sd_writel(priv, tmp, TMIO_SD_SOFT_RST);
	tmp |= TMIO_SD_SOFT_RST_RSTX;
	tmio_sd_writel(priv, tmp, TMIO_SD_SOFT_RST);

	/* FIXME: implement eMMC hw_reset */

	tmio_sd_writel(priv, TMIO_SD_STOP_SEC, TMIO_SD_STOP);

	/*
	 * Connected to 32bit AXI.
	 * This register dropped backward compatibility at version 0x10.
	 * Write an appropriate value depending on the IP version.
	 */
	if (priv->version >= 0x10) {
		if (priv->caps & TMIO_SD_CAP_64BIT)
			tmio_sd_writel(priv, 0x000, TMIO_SD_HOST_MODE);
		else
			tmio_sd_writel(priv, 0x101, TMIO_SD_HOST_MODE);
	} else {
		tmio_sd_writel(priv, 0x0, TMIO_SD_HOST_MODE);
	}

	if (priv->caps & TMIO_SD_CAP_DMA_INTERNAL) {
		tmp = tmio_sd_readl(priv, TMIO_SD_DMA_MODE);
		tmp |= TMIO_SD_DMA_MODE_ADDR_INC;
		tmio_sd_writel(priv, tmp, TMIO_SD_DMA_MODE);
	}
}

int tmio_sd_bind(struct udevice *dev)
{
	struct tmio_sd_plat *plat = dev_get_platdata(dev);

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

int tmio_sd_probe(struct udevice *dev, u32 quirks)
{
	struct tmio_sd_plat *plat = dev_get_platdata(dev);
	struct tmio_sd_priv *priv = dev_get_priv(dev);
	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
	fdt_addr_t base;
	ulong mclk;
	int ret;

	base = devfdt_get_addr(dev);
	if (base == FDT_ADDR_T_NONE)
		return -EINVAL;

	priv->regbase = devm_ioremap(dev, base, SZ_2K);
	if (!priv->regbase)
		return -ENOMEM;

#ifdef CONFIG_DM_REGULATOR
	device_get_supply_regulator(dev, "vqmmc-supply", &priv->vqmmc_dev);
	if (priv->vqmmc_dev)
		regulator_set_value(priv->vqmmc_dev, 3300000);
#endif

	ret = mmc_of_parse(dev, &plat->cfg);
	if (ret < 0) {
		dev_err(dev, "failed to parse host caps\n");
		return ret;
	}

	plat->cfg.name = dev->name;
	plat->cfg.host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;

	if (quirks)
		priv->caps = quirks;

	priv->version = tmio_sd_readl(priv, TMIO_SD_VERSION) &
						TMIO_SD_VERSION_IP;
	dev_dbg(dev, "version %x\n", priv->version);
	if (priv->version >= 0x10) {
		priv->caps |= TMIO_SD_CAP_DMA_INTERNAL;
		priv->caps |= TMIO_SD_CAP_DIV1024;
	}

	if (fdt_get_property(gd->fdt_blob, dev_of_offset(dev), "non-removable",
			     NULL))
		priv->caps |= TMIO_SD_CAP_NONREMOVABLE;

	tmio_sd_host_init(priv);

	mclk = tmio_sd_clk_get_rate(priv);

	plat->cfg.voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34;
	plat->cfg.f_min = mclk /
			(priv->caps & TMIO_SD_CAP_DIV1024 ? 1024 : 512);
	plat->cfg.f_max = mclk;
	if (quirks & TMIO_SD_CAP_16BIT)
		plat->cfg.b_max = U16_MAX; /* max value of TMIO_SD_SECCNT */
	else
		plat->cfg.b_max = U32_MAX; /* max value of TMIO_SD_SECCNT */

	upriv->mmc = &plat->mmc;

	return 0;
}
