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

#include <common.h>
#include <clk.h>
#include <fdtdec.h>
#include <mmc.h>
#include <dm.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 "matsushita-common.h"

DECLARE_GLOBAL_DATA_PTR;

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

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

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

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

u32 matsu_sd_readl(struct matsu_sd_priv *priv, unsigned int reg)
{
	u32 val;

	if (priv->caps & MATSU_SD_CAP_64BIT)
		return readl(priv->regbase + (reg << 1));
	else if (priv->caps & MATSU_SD_CAP_16BIT) {
		val = readw(priv->regbase + (reg >> 1)) & 0xffff;
		if ((reg == MATSU_SD_RSP10) || (reg == MATSU_SD_RSP32) ||
		    (reg == MATSU_SD_RSP54) || (reg == MATSU_SD_RSP76)) {
			val |= readw(priv->regbase + (reg >> 1) + 2) << 16;
		}
		return val;
	} else
		return readl(priv->regbase + reg);
}

void matsu_sd_writel(struct matsu_sd_priv *priv,
			       u32 val, unsigned int reg)
{
	if (priv->caps & MATSU_SD_CAP_64BIT)
		writel(val, priv->regbase + (reg << 1));
	else if (priv->caps & MATSU_SD_CAP_16BIT) {
		writew(val & 0xffff, priv->regbase + (reg >> 1));
		if (reg == MATSU_SD_INFO1 || reg == MATSU_SD_INFO1_MASK ||
		    reg == MATSU_SD_INFO2 || reg == MATSU_SD_INFO2_MASK ||
		    reg == MATSU_SD_ARG)
			writew(val >> 16, priv->regbase + (reg >> 1) + 2);
	} else
		writel(val, priv->regbase + reg);
}

static dma_addr_t __dma_map_single(void *ptr, size_t size,
				   enum dma_data_direction dir)
{
	unsigned long addr = (unsigned long)ptr;

	if (dir == DMA_FROM_DEVICE)
		invalidate_dcache_range(addr, addr + size);
	else
		flush_dcache_range(addr, addr + size);

	return addr;
}

static void __dma_unmap_single(dma_addr_t addr, size_t size,
			       enum dma_data_direction dir)
{
	if (dir != DMA_TO_DEVICE)
		invalidate_dcache_range(addr, addr + size);
}

static int matsu_sd_check_error(struct udevice *dev)
{
	struct matsu_sd_priv *priv = dev_get_priv(dev);
	u32 info2 = matsu_sd_readl(priv, MATSU_SD_INFO2);

	if (info2 & MATSU_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 & MATSU_SD_INFO2_ERR_TO) {
		dev_err(dev, "timeout error\n");
		return -ETIMEDOUT;
	}

	if (info2 & (MATSU_SD_INFO2_ERR_END | MATSU_SD_INFO2_ERR_CRC |
		     MATSU_SD_INFO2_ERR_IDX)) {
		dev_err(dev, "communication out of sync\n");
		return -EILSEQ;
	}

	if (info2 & (MATSU_SD_INFO2_ERR_ILA | MATSU_SD_INFO2_ERR_ILR |
		     MATSU_SD_INFO2_ERR_ILW)) {
		dev_err(dev, "illegal access\n");
		return -EIO;
	}

	return 0;
}

static int matsu_sd_wait_for_irq(struct udevice *dev, unsigned int reg,
				    u32 flag)
{
	struct matsu_sd_priv *priv = dev_get_priv(dev);
	long wait = 1000000;
	int ret;

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

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

		udelay(1);
	}

	return 0;
}

#define matsu_pio_read_fifo(__width, __suffix)				\
static void matsu_pio_read_fifo_##__width(struct matsu_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++ = matsu_sd_read##__suffix(priv,		\
							 MATSU_SD_BUF);	\
		}							\
	} else {							\
		for (i = 0; i < blksz / ((__width) / 8); i++) {		\
			u##__width data;				\
			data = matsu_sd_read##__suffix(priv,		\
						       MATSU_SD_BUF);	\
			put_unaligned(data, buf++);			\
		}							\
	}								\
}

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

static int matsu_sd_pio_read_one_block(struct udevice *dev, char *pbuf,
					  uint blocksize)
{
	struct matsu_sd_priv *priv = dev_get_priv(dev);
	int ret;

	/* wait until the buffer is filled with data */
	ret = matsu_sd_wait_for_irq(dev, MATSU_SD_INFO2,
				       MATSU_SD_INFO2_BRE);
	if (ret)
		return ret;

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

	if (priv->caps & MATSU_SD_CAP_64BIT)
		matsu_pio_read_fifo_64(priv, pbuf, blocksize);
	else if (priv->caps & MATSU_SD_CAP_16BIT)
		matsu_pio_read_fifo_16(priv, pbuf, blocksize);
	else
		matsu_pio_read_fifo_32(priv, pbuf, blocksize);

	return 0;
}

#define matsu_pio_write_fifo(__width, __suffix)				\
static void matsu_pio_write_fifo_##__width(struct matsu_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++) {		\
			matsu_sd_write##__suffix(priv, *buf++,		\
						 MATSU_SD_BUF);		\
		}							\
	} else {							\
		for (i = 0; i < blksz / ((__width) / 8); i++) {		\
			u##__width data = get_unaligned(buf++);		\
			matsu_sd_write##__suffix(priv, data,		\
						 MATSU_SD_BUF);		\
		}							\
	}								\
}

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

static int matsu_sd_pio_write_one_block(struct udevice *dev,
					   const char *pbuf, uint blocksize)
{
	struct matsu_sd_priv *priv = dev_get_priv(dev);
	int ret;

	/* wait until the buffer becomes empty */
	ret = matsu_sd_wait_for_irq(dev, MATSU_SD_INFO2,
				    MATSU_SD_INFO2_BWE);
	if (ret)
		return ret;

	matsu_sd_writel(priv, 0, MATSU_SD_INFO2);

	if (priv->caps & MATSU_SD_CAP_64BIT)
		matsu_pio_write_fifo_64(priv, pbuf, blocksize);
	else if (priv->caps & MATSU_SD_CAP_16BIT)
		matsu_pio_write_fifo_16(priv, pbuf, blocksize);
	else
		matsu_pio_write_fifo_32(priv, pbuf, blocksize);

	return 0;
}

static int matsu_sd_pio_xfer(struct udevice *dev, 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 = matsu_sd_pio_read_one_block(dev, dest,
							     data->blocksize);
		else
			ret = matsu_sd_pio_write_one_block(dev, src,
							      data->blocksize);
		if (ret)
			return ret;

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

	return 0;
}

static void matsu_sd_dma_start(struct matsu_sd_priv *priv,
				  dma_addr_t dma_addr)
{
	u32 tmp;

	matsu_sd_writel(priv, 0, MATSU_SD_DMA_INFO1);
	matsu_sd_writel(priv, 0, MATSU_SD_DMA_INFO2);

	/* enable DMA */
	tmp = matsu_sd_readl(priv, MATSU_SD_EXTMODE);
	tmp |= MATSU_SD_EXTMODE_DMA_EN;
	matsu_sd_writel(priv, tmp, MATSU_SD_EXTMODE);

	matsu_sd_writel(priv, dma_addr & U32_MAX, MATSU_SD_DMA_ADDR_L);

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

	matsu_sd_writel(priv, dma_addr & U32_MAX, MATSU_SD_DMA_ADDR_H);

	matsu_sd_writel(priv, MATSU_SD_DMA_CTL_START, MATSU_SD_DMA_CTL);
}

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

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

		udelay(10);
	}

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

	return 0;
}

static int matsu_sd_dma_xfer(struct udevice *dev, struct mmc_data *data)
{
	struct matsu_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 = matsu_sd_readl(priv, MATSU_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 bit 17 on
		 * Renesas SoCs and bit 20 does not work on them.
		 */
		poll_flag = (priv->caps & MATSU_SD_CAP_RCAR) ?
			    MATSU_SD_DMA_INFO1_END_RD :
			    MATSU_SD_DMA_INFO1_END_RD2;
		tmp |= MATSU_SD_DMA_MODE_DIR_RD;
	} else {
		buf = (void *)data->src;
		dir = DMA_TO_DEVICE;
		poll_flag = MATSU_SD_DMA_INFO1_END_WR;
		tmp &= ~MATSU_SD_DMA_MODE_DIR_RD;
	}

	matsu_sd_writel(priv, tmp, MATSU_SD_DMA_MODE);

	dma_addr = __dma_map_single(buf, len, dir);

	matsu_sd_dma_start(priv, dma_addr);

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

	__dma_unmap_single(dma_addr, len, dir);

	return ret;
}

/* check if the address is DMA'able */
static bool matsu_sd_addr_is_dmaable(unsigned long addr)
{
	if (!IS_ALIGNED(addr, MATSU_SD_DMA_MINALIGN))
		return false;

#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 matsu_sd_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
		      struct mmc_data *data)
{
	struct matsu_sd_priv *priv = dev_get_priv(dev);
	int ret;
	u32 tmp;

	if (matsu_sd_readl(priv, MATSU_SD_INFO2) & MATSU_SD_INFO2_CBSY) {
		dev_err(dev, "command busy\n");
		return -EBUSY;
	}

	/* clear all status flags */
	matsu_sd_writel(priv, 0, MATSU_SD_INFO1);
	matsu_sd_writel(priv, 0, MATSU_SD_INFO2);

	/* disable DMA once */
	tmp = matsu_sd_readl(priv, MATSU_SD_EXTMODE);
	tmp &= ~MATSU_SD_EXTMODE_DMA_EN;
	matsu_sd_writel(priv, tmp, MATSU_SD_EXTMODE);

	matsu_sd_writel(priv, cmd->cmdarg, MATSU_SD_ARG);

	tmp = cmd->cmdidx;

	if (data) {
		matsu_sd_writel(priv, data->blocksize, MATSU_SD_SIZE);
		matsu_sd_writel(priv, data->blocks, MATSU_SD_SECCNT);

		/* Do not send CMD12 automatically */
		tmp |= MATSU_SD_CMD_NOSTOP | MATSU_SD_CMD_DATA;

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

		if (data->flags & MMC_DATA_READ)
			tmp |= MATSU_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 |= MATSU_SD_CMD_RSP_NONE;
		break;
	case MMC_RSP_R1:
		tmp |= MATSU_SD_CMD_RSP_R1;
		break;
	case MMC_RSP_R1b:
		tmp |= MATSU_SD_CMD_RSP_R1B;
		break;
	case MMC_RSP_R2:
		tmp |= MATSU_SD_CMD_RSP_R2;
		break;
	case MMC_RSP_R3:
		tmp |= MATSU_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);
	matsu_sd_writel(priv, tmp, MATSU_SD_CMD);

	ret = matsu_sd_wait_for_irq(dev, MATSU_SD_INFO1,
				       MATSU_SD_INFO1_RSP);
	if (ret)
		return ret;

	if (cmd->resp_type & MMC_RSP_136) {
		u32 rsp_127_104 = matsu_sd_readl(priv, MATSU_SD_RSP76);
		u32 rsp_103_72 = matsu_sd_readl(priv, MATSU_SD_RSP54);
		u32 rsp_71_40 = matsu_sd_readl(priv, MATSU_SD_RSP32);
		u32 rsp_39_8 = matsu_sd_readl(priv, MATSU_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] = matsu_sd_readl(priv, MATSU_SD_RSP10);
	}

	if (data) {
		/* use DMA if the HW supports it and the buffer is aligned */
		if (priv->caps & MATSU_SD_CAP_DMA_INTERNAL &&
		    matsu_sd_addr_is_dmaable((long)data->src))
			ret = matsu_sd_dma_xfer(dev, data);
		else
			ret = matsu_sd_pio_xfer(dev, data);

		ret = matsu_sd_wait_for_irq(dev, MATSU_SD_INFO1,
					       MATSU_SD_INFO1_CMP);
		if (ret)
			return ret;
	}

	matsu_sd_wait_for_irq(dev, MATSU_SD_INFO2, MATSU_SD_INFO2_SCLKDIVEN);

	return ret;
}

static int matsu_sd_set_bus_width(struct matsu_sd_priv *priv,
				     struct mmc *mmc)
{
	u32 val, tmp;

	switch (mmc->bus_width) {
	case 0:
	case 1:
		val = MATSU_SD_OPTION_WIDTH_1;
		break;
	case 4:
		val = MATSU_SD_OPTION_WIDTH_4;
		break;
	case 8:
		val = MATSU_SD_OPTION_WIDTH_8;
		break;
	default:
		return -EINVAL;
	}

	tmp = matsu_sd_readl(priv, MATSU_SD_OPTION);
	tmp &= ~MATSU_SD_OPTION_WIDTH_MASK;
	tmp |= val;
	matsu_sd_writel(priv, tmp, MATSU_SD_OPTION);

	return 0;
}

static void matsu_sd_set_ddr_mode(struct matsu_sd_priv *priv,
				     struct mmc *mmc)
{
	u32 tmp;

	tmp = matsu_sd_readl(priv, MATSU_SD_IF_MODE);
	if (mmc->ddr_mode)
		tmp |= MATSU_SD_IF_MODE_DDR;
	else
		tmp &= ~MATSU_SD_IF_MODE_DDR;
	matsu_sd_writel(priv, tmp, MATSU_SD_IF_MODE);
}

static void matsu_sd_set_clk_rate(struct matsu_sd_priv *priv,
				     struct mmc *mmc)
{
	unsigned int divisor;
	u32 val, tmp;

	if (!mmc->clock)
		return;

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

	if (divisor <= 1)
		val = (priv->caps & MATSU_SD_CAP_RCAR) ?
		      MATSU_SD_CLKCTL_RCAR_DIV1 : MATSU_SD_CLKCTL_DIV1;
	else if (divisor <= 2)
		val = MATSU_SD_CLKCTL_DIV2;
	else if (divisor <= 4)
		val = MATSU_SD_CLKCTL_DIV4;
	else if (divisor <= 8)
		val = MATSU_SD_CLKCTL_DIV8;
	else if (divisor <= 16)
		val = MATSU_SD_CLKCTL_DIV16;
	else if (divisor <= 32)
		val = MATSU_SD_CLKCTL_DIV32;
	else if (divisor <= 64)
		val = MATSU_SD_CLKCTL_DIV64;
	else if (divisor <= 128)
		val = MATSU_SD_CLKCTL_DIV128;
	else if (divisor <= 256)
		val = MATSU_SD_CLKCTL_DIV256;
	else if (divisor <= 512 || !(priv->caps & MATSU_SD_CAP_DIV1024))
		val = MATSU_SD_CLKCTL_DIV512;
	else
		val = MATSU_SD_CLKCTL_DIV1024;

	tmp = matsu_sd_readl(priv, MATSU_SD_CLKCTL);
	if (tmp & MATSU_SD_CLKCTL_SCLKEN &&
	    (tmp & MATSU_SD_CLKCTL_DIV_MASK) == val)
		return;

	/* stop the clock before changing its rate to avoid a glitch signal */
	tmp &= ~MATSU_SD_CLKCTL_SCLKEN;
	matsu_sd_writel(priv, tmp, MATSU_SD_CLKCTL);

	tmp &= ~MATSU_SD_CLKCTL_DIV_MASK;
	tmp |= val | MATSU_SD_CLKCTL_OFFEN;
	matsu_sd_writel(priv, tmp, MATSU_SD_CLKCTL);

	tmp |= MATSU_SD_CLKCTL_SCLKEN;
	matsu_sd_writel(priv, tmp, MATSU_SD_CLKCTL);

	udelay(1000);
}

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

#ifdef CONFIG_DM_REGULATOR
	struct matsu_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
	switch (mmc->selected_mode) {
	case MMC_LEGACY:
	case SD_LEGACY:
	case MMC_HS:
	case SD_HS:
	case MMC_HS_52:
	case MMC_DDR_52:
		pinctrl_select_state(dev, "default");
		break;
	case UHS_SDR12:
	case UHS_SDR25:
	case UHS_SDR50:
	case UHS_DDR50:
	case UHS_SDR104:
	case MMC_HS_200:
		pinctrl_select_state(dev, "state_uhs");
		break;
	default:
		break;
	}
#endif
}

int matsu_sd_set_ios(struct udevice *dev)
{
	struct matsu_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);

	ret = matsu_sd_set_bus_width(priv, mmc);
	if (ret)
		return ret;
	matsu_sd_set_ddr_mode(priv, mmc);
	matsu_sd_set_clk_rate(priv, mmc);
	matsu_sd_set_pins(dev);

	return 0;
}

int matsu_sd_get_cd(struct udevice *dev)
{
	struct matsu_sd_priv *priv = dev_get_priv(dev);

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

	return !!(matsu_sd_readl(priv, MATSU_SD_INFO1) &
		  MATSU_SD_INFO1_CD);
}

static void matsu_sd_host_init(struct matsu_sd_priv *priv)
{
	u32 tmp;

	/* soft reset of the host */
	tmp = matsu_sd_readl(priv, MATSU_SD_SOFT_RST);
	tmp &= ~MATSU_SD_SOFT_RST_RSTX;
	matsu_sd_writel(priv, tmp, MATSU_SD_SOFT_RST);
	tmp |= MATSU_SD_SOFT_RST_RSTX;
	matsu_sd_writel(priv, tmp, MATSU_SD_SOFT_RST);

	/* FIXME: implement eMMC hw_reset */

	matsu_sd_writel(priv, MATSU_SD_STOP_SEC, MATSU_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)
		matsu_sd_writel(priv, 0x101, MATSU_SD_HOST_MODE);
	else
		matsu_sd_writel(priv, 0x0, MATSU_SD_HOST_MODE);

	if (priv->caps & MATSU_SD_CAP_DMA_INTERNAL) {
		tmp = matsu_sd_readl(priv, MATSU_SD_DMA_MODE);
		tmp |= MATSU_SD_DMA_MODE_ADDR_INC;
		matsu_sd_writel(priv, tmp, MATSU_SD_DMA_MODE);
	}
}

int matsu_sd_bind(struct udevice *dev)
{
	struct matsu_sd_plat *plat = dev_get_platdata(dev);

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

int matsu_sd_probe(struct udevice *dev, u32 quirks)
{
	struct matsu_sd_plat *plat = dev_get_platdata(dev);
	struct matsu_sd_priv *priv = dev_get_priv(dev);
	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
	fdt_addr_t base;
	struct clk clk;
	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);
#endif

	ret = clk_get_by_index(dev, 0, &clk);
	if (ret < 0) {
		dev_err(dev, "failed to get host clock\n");
		return ret;
	}

	/* set to max rate */
	priv->mclk = clk_set_rate(&clk, ULONG_MAX);
	if (IS_ERR_VALUE(priv->mclk)) {
		dev_err(dev, "failed to set rate for host clock\n");
		clk_free(&clk);
		return priv->mclk;
	}

	ret = clk_enable(&clk);
	clk_free(&clk);
	if (ret) {
		dev_err(dev, "failed to enable host clock\n");
		return ret;
	}

	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 = matsu_sd_readl(priv, MATSU_SD_VERSION) &
						MATSU_SD_VERSION_IP;
	dev_dbg(dev, "version %x\n", priv->version);
	if (priv->version >= 0x10) {
		priv->caps |= MATSU_SD_CAP_DMA_INTERNAL;
		priv->caps |= MATSU_SD_CAP_DIV1024;
	}

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

	matsu_sd_host_init(priv);

	plat->cfg.voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34;
	plat->cfg.f_min = priv->mclk /
			(priv->caps & MATSU_SD_CAP_DIV1024 ? 1024 : 512);
	plat->cfg.f_max = priv->mclk;
	plat->cfg.b_max = U32_MAX; /* max value of MATSU_SD_SECCNT */

	upriv->mmc = &plat->mmc;

	return 0;
}
