// SPDX-License-Identifier: GPL-2.0
/*
 * MMCIF driver.
 *
 * Copyright (C)  2011 Renesas Solutions Corp.
 */

#include <config.h>
#include <common.h>
#include <log.h>
#include <watchdog.h>
#include <command.h>
#include <mmc.h>
#include <clk.h>
#include <dm.h>
#include <malloc.h>
#include <dm/device_compat.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/compat.h>
#include <linux/io.h>
#include <linux/sizes.h>
#include "sh_mmcif.h"
#include <asm/global_data.h>

#define DRIVER_NAME	"sh_mmcif"

static int sh_mmcif_intr(void *dev_id)
{
	struct sh_mmcif_host *host = dev_id;
	u32 state = 0;

	state = sh_mmcif_read(&host->regs->ce_int);
	state &= sh_mmcif_read(&host->regs->ce_int_mask);

	if (state & INT_RBSYE) {
		sh_mmcif_write(~(INT_RBSYE | INT_CRSPE), &host->regs->ce_int);
		sh_mmcif_bitclr(MASK_MRBSYE, &host->regs->ce_int_mask);
		goto end;
	} else if (state & INT_CRSPE) {
		sh_mmcif_write(~INT_CRSPE, &host->regs->ce_int);
		sh_mmcif_bitclr(MASK_MCRSPE, &host->regs->ce_int_mask);
		/* one more interrupt (INT_RBSYE) */
		if (sh_mmcif_read(&host->regs->ce_cmd_set) & CMD_SET_RBSY)
			return -EAGAIN;
		goto end;
	} else if (state & INT_BUFREN) {
		sh_mmcif_write(~INT_BUFREN, &host->regs->ce_int);
		sh_mmcif_bitclr(MASK_MBUFREN, &host->regs->ce_int_mask);
		goto end;
	} else if (state & INT_BUFWEN) {
		sh_mmcif_write(~INT_BUFWEN, &host->regs->ce_int);
		sh_mmcif_bitclr(MASK_MBUFWEN, &host->regs->ce_int_mask);
		goto end;
	} else if (state & INT_CMD12DRE) {
		sh_mmcif_write(~(INT_CMD12DRE | INT_CMD12RBE | INT_CMD12CRE |
				  INT_BUFRE), &host->regs->ce_int);
		sh_mmcif_bitclr(MASK_MCMD12DRE, &host->regs->ce_int_mask);
		goto end;
	} else if (state & INT_BUFRE) {
		sh_mmcif_write(~INT_BUFRE, &host->regs->ce_int);
		sh_mmcif_bitclr(MASK_MBUFRE, &host->regs->ce_int_mask);
		goto end;
	} else if (state & INT_DTRANE) {
		sh_mmcif_write(~INT_DTRANE, &host->regs->ce_int);
		sh_mmcif_bitclr(MASK_MDTRANE, &host->regs->ce_int_mask);
		goto end;
	} else if (state & INT_CMD12RBE) {
		sh_mmcif_write(~(INT_CMD12RBE | INT_CMD12CRE),
				&host->regs->ce_int);
		sh_mmcif_bitclr(MASK_MCMD12RBE, &host->regs->ce_int_mask);
		goto end;
	} else if (state & INT_ERR_STS) {
		/* err interrupts */
		sh_mmcif_write(~state, &host->regs->ce_int);
		sh_mmcif_bitclr(state, &host->regs->ce_int_mask);
		goto err;
	} else
		return -EAGAIN;

err:
	host->sd_error = 1;
	debug("%s: int err state = %08x\n", DRIVER_NAME, state);
end:
	host->wait_int = 1;
	return 0;
}

static int mmcif_wait_interrupt_flag(struct sh_mmcif_host *host)
{
	int timeout = 10000000;

	while (1) {
		timeout--;
		if (timeout < 0) {
			printf("timeout\n");
			return 0;
		}

		if (!sh_mmcif_intr(host))
			break;

		udelay(1);	/* 1 usec */
	}

	return 1;	/* Return value: NOT 0 = complete waiting */
}

static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk)
{
	sh_mmcif_bitclr(CLK_ENABLE, &host->regs->ce_clk_ctrl);
	sh_mmcif_bitclr(CLK_CLEAR, &host->regs->ce_clk_ctrl);

	if (!clk)
		return;

	if (clk == CLKDEV_EMMC_DATA)
		sh_mmcif_bitset(CLK_PCLK, &host->regs->ce_clk_ctrl);
	else
		sh_mmcif_bitset((fls(DIV_ROUND_UP(host->clk,
						  clk) - 1) - 1) << 16,
				&host->regs->ce_clk_ctrl);
	sh_mmcif_bitset(CLK_ENABLE, &host->regs->ce_clk_ctrl);
}

static void sh_mmcif_sync_reset(struct sh_mmcif_host *host)
{
	u32 tmp;

	tmp = sh_mmcif_read(&host->regs->ce_clk_ctrl) & (CLK_ENABLE |
							 CLK_CLEAR);

	sh_mmcif_write(SOFT_RST_ON, &host->regs->ce_version);
	sh_mmcif_write(SOFT_RST_OFF, &host->regs->ce_version);
	sh_mmcif_bitset(tmp | SRSPTO_256 | SRBSYTO_29 | SRWDTO_29 | SCCSTO_29,
			&host->regs->ce_clk_ctrl);
	/* byte swap on */
	sh_mmcif_bitset(BUF_ACC_ATYP, &host->regs->ce_buf_acc);
}

static int sh_mmcif_error_manage(struct sh_mmcif_host *host)
{
	u32 state1, state2;
	int ret, timeout = 10000000;

	host->sd_error = 0;
	host->wait_int = 0;

	state1 = sh_mmcif_read(&host->regs->ce_host_sts1);
	state2 = sh_mmcif_read(&host->regs->ce_host_sts2);
	debug("%s: ERR HOST_STS1 = %08x\n", \
			DRIVER_NAME, sh_mmcif_read(&host->regs->ce_host_sts1));
	debug("%s: ERR HOST_STS2 = %08x\n", \
			DRIVER_NAME, sh_mmcif_read(&host->regs->ce_host_sts2));

	if (state1 & STS1_CMDSEQ) {
		debug("%s: Forced end of command sequence\n", DRIVER_NAME);
		sh_mmcif_bitset(CMD_CTRL_BREAK, &host->regs->ce_cmd_ctrl);
		sh_mmcif_bitset(~CMD_CTRL_BREAK, &host->regs->ce_cmd_ctrl);
		while (1) {
			timeout--;
			if (timeout < 0) {
				printf(DRIVER_NAME": Forceed end of " \
					"command sequence timeout err\n");
				return -EILSEQ;
			}
			if (!(sh_mmcif_read(&host->regs->ce_host_sts1)
								& STS1_CMDSEQ))
				break;
		}
		sh_mmcif_sync_reset(host);
		return -EILSEQ;
	}

	if (state2 & STS2_CRC_ERR)
		ret = -EILSEQ;
	else if (state2 & STS2_TIMEOUT_ERR)
		ret = -ETIMEDOUT;
	else
		ret = -EILSEQ;
	return ret;
}

static int sh_mmcif_single_read(struct sh_mmcif_host *host,
				struct mmc_data *data)
{
	long time;
	u32 blocksize, i;
	unsigned long *p = (unsigned long *)data->dest;

	if ((unsigned long)p & 0x00000001) {
		printf("%s: The data pointer is unaligned.", __func__);
		return -EIO;
	}

	host->wait_int = 0;

	/* buf read enable */
	sh_mmcif_bitset(MASK_MBUFREN, &host->regs->ce_int_mask);
	time = mmcif_wait_interrupt_flag(host);
	if (time == 0 || host->sd_error != 0)
		return sh_mmcif_error_manage(host);

	host->wait_int = 0;
	blocksize = (BLOCK_SIZE_MASK &
			sh_mmcif_read(&host->regs->ce_block_set)) + 3;
	for (i = 0; i < blocksize / 4; i++)
		*p++ = sh_mmcif_read(&host->regs->ce_data);

	/* buffer read end */
	sh_mmcif_bitset(MASK_MBUFRE, &host->regs->ce_int_mask);
	time = mmcif_wait_interrupt_flag(host);
	if (time == 0 || host->sd_error != 0)
		return sh_mmcif_error_manage(host);

	host->wait_int = 0;
	return 0;
}

static int sh_mmcif_multi_read(struct sh_mmcif_host *host,
				struct mmc_data *data)
{
	long time;
	u32 blocksize, i, j;
	unsigned long *p = (unsigned long *)data->dest;

	if ((unsigned long)p & 0x00000001) {
		printf("%s: The data pointer is unaligned.", __func__);
		return -EIO;
	}

	host->wait_int = 0;
	blocksize = BLOCK_SIZE_MASK & sh_mmcif_read(&host->regs->ce_block_set);
	for (j = 0; j < data->blocks; j++) {
		sh_mmcif_bitset(MASK_MBUFREN, &host->regs->ce_int_mask);
		time = mmcif_wait_interrupt_flag(host);
		if (time == 0 || host->sd_error != 0)
			return sh_mmcif_error_manage(host);

		host->wait_int = 0;
		for (i = 0; i < blocksize / 4; i++)
			*p++ = sh_mmcif_read(&host->regs->ce_data);

		schedule();
	}
	return 0;
}

static int sh_mmcif_single_write(struct sh_mmcif_host *host,
				 struct mmc_data *data)
{
	long time;
	u32 blocksize, i;
	const unsigned long *p = (unsigned long *)data->dest;

	if ((unsigned long)p & 0x00000001) {
		printf("%s: The data pointer is unaligned.", __func__);
		return -EIO;
	}

	host->wait_int = 0;
	sh_mmcif_bitset(MASK_MBUFWEN, &host->regs->ce_int_mask);

	time = mmcif_wait_interrupt_flag(host);
	if (time == 0 || host->sd_error != 0)
		return sh_mmcif_error_manage(host);

	host->wait_int = 0;
	blocksize = (BLOCK_SIZE_MASK &
			sh_mmcif_read(&host->regs->ce_block_set)) + 3;
	for (i = 0; i < blocksize / 4; i++)
		sh_mmcif_write(*p++, &host->regs->ce_data);

	/* buffer write end */
	sh_mmcif_bitset(MASK_MDTRANE, &host->regs->ce_int_mask);

	time = mmcif_wait_interrupt_flag(host);
	if (time == 0 || host->sd_error != 0)
		return sh_mmcif_error_manage(host);

	host->wait_int = 0;
	return 0;
}

static int sh_mmcif_multi_write(struct sh_mmcif_host *host,
				struct mmc_data *data)
{
	long time;
	u32 i, j, blocksize;
	const unsigned long *p = (unsigned long *)data->dest;

	if ((unsigned long)p & 0x00000001) {
		printf("%s: The data pointer is unaligned.", __func__);
		return -EIO;
	}

	host->wait_int = 0;
	blocksize = BLOCK_SIZE_MASK & sh_mmcif_read(&host->regs->ce_block_set);
	for (j = 0; j < data->blocks; j++) {
		sh_mmcif_bitset(MASK_MBUFWEN, &host->regs->ce_int_mask);

		time = mmcif_wait_interrupt_flag(host);

		if (time == 0 || host->sd_error != 0)
			return sh_mmcif_error_manage(host);

		host->wait_int = 0;
		for (i = 0; i < blocksize / 4; i++)
			sh_mmcif_write(*p++, &host->regs->ce_data);

		schedule();
	}
	return 0;
}

static void sh_mmcif_get_response(struct sh_mmcif_host *host,
					struct mmc_cmd *cmd)
{
	if (cmd->resp_type & MMC_RSP_136) {
		cmd->response[0] = sh_mmcif_read(&host->regs->ce_resp3);
		cmd->response[1] = sh_mmcif_read(&host->regs->ce_resp2);
		cmd->response[2] = sh_mmcif_read(&host->regs->ce_resp1);
		cmd->response[3] = sh_mmcif_read(&host->regs->ce_resp0);
		debug(" RESP %08x, %08x, %08x, %08x\n", cmd->response[0],
			 cmd->response[1], cmd->response[2], cmd->response[3]);
	} else {
		cmd->response[0] = sh_mmcif_read(&host->regs->ce_resp0);
	}
}

static void sh_mmcif_get_cmd12response(struct sh_mmcif_host *host,
					struct mmc_cmd *cmd)
{
	cmd->response[0] = sh_mmcif_read(&host->regs->ce_resp_cmd12);
}

static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
				struct mmc_data *data, struct mmc_cmd *cmd)
{
	u32 tmp = 0;
	u32 opc = cmd->cmdidx;

	/* Response Type check */
	switch (cmd->resp_type) {
	case MMC_RSP_NONE:
		tmp |= CMD_SET_RTYP_NO;
		break;
	case MMC_RSP_R1:
	case MMC_RSP_R1b:
	case MMC_RSP_R3:
		tmp |= CMD_SET_RTYP_6B;
		break;
	case MMC_RSP_R2:
		tmp |= CMD_SET_RTYP_17B;
		break;
	default:
		printf(DRIVER_NAME": Not support type response.\n");
		break;
	}

	/* RBSY */
	if (opc == MMC_CMD_SWITCH)
		tmp |= CMD_SET_RBSY;

	/* WDAT / DATW */
	if (host->data) {
		tmp |= CMD_SET_WDAT;
		switch (host->bus_width) {
		case MMC_BUS_WIDTH_1:
			tmp |= CMD_SET_DATW_1;
			break;
		case MMC_BUS_WIDTH_4:
			tmp |= CMD_SET_DATW_4;
			break;
		case MMC_BUS_WIDTH_8:
			tmp |= CMD_SET_DATW_8;
			break;
		default:
			printf(DRIVER_NAME": Not support bus width.\n");
			break;
		}
	}
	/* DWEN */
	if (opc == MMC_CMD_WRITE_SINGLE_BLOCK ||
	    opc == MMC_CMD_WRITE_MULTIPLE_BLOCK)
		tmp |= CMD_SET_DWEN;
	/* CMLTE/CMD12EN */
	if (opc == MMC_CMD_READ_MULTIPLE_BLOCK ||
	    opc == MMC_CMD_WRITE_MULTIPLE_BLOCK) {
		tmp |= CMD_SET_CMLTE | CMD_SET_CMD12EN;
		sh_mmcif_bitset(data->blocks << 16, &host->regs->ce_block_set);
	}
	/* RIDXC[1:0] check bits */
	if (opc == MMC_CMD_SEND_OP_COND || opc == MMC_CMD_ALL_SEND_CID ||
	    opc == MMC_CMD_SEND_CSD || opc == MMC_CMD_SEND_CID)
		tmp |= CMD_SET_RIDXC_BITS;
	/* RCRC7C[1:0] check bits */
	if (opc == MMC_CMD_SEND_OP_COND)
		tmp |= CMD_SET_CRC7C_BITS;
	/* RCRC7C[1:0] internal CRC7 */
	if (opc == MMC_CMD_ALL_SEND_CID ||
		opc == MMC_CMD_SEND_CSD || opc == MMC_CMD_SEND_CID)
		tmp |= CMD_SET_CRC7C_INTERNAL;

	return opc = ((opc << 24) | tmp);
}

static u32 sh_mmcif_data_trans(struct sh_mmcif_host *host,
				struct mmc_data *data, u16 opc)
{
	u32 ret;

	switch (opc) {
	case MMC_CMD_READ_MULTIPLE_BLOCK:
		ret = sh_mmcif_multi_read(host, data);
		break;
	case MMC_CMD_WRITE_MULTIPLE_BLOCK:
		ret = sh_mmcif_multi_write(host, data);
		break;
	case MMC_CMD_WRITE_SINGLE_BLOCK:
		ret = sh_mmcif_single_write(host, data);
		break;
	case MMC_CMD_READ_SINGLE_BLOCK:
	case MMC_CMD_SEND_EXT_CSD:
		ret = sh_mmcif_single_read(host, data);
		break;
	default:
		printf(DRIVER_NAME": NOT SUPPORT CMD = d'%08d\n", opc);
		ret = -EINVAL;
		break;
	}
	return ret;
}

static int sh_mmcif_start_cmd(struct sh_mmcif_host *host,
				struct mmc_data *data, struct mmc_cmd *cmd)
{
	long time;
	int ret = 0, mask = 0;
	u32 opc = cmd->cmdidx;

	if (opc == MMC_CMD_STOP_TRANSMISSION) {
		/* MMCIF sends the STOP command automatically */
		if (host->last_cmd == MMC_CMD_READ_MULTIPLE_BLOCK)
			sh_mmcif_bitset(MASK_MCMD12DRE,
					&host->regs->ce_int_mask);
		else
			sh_mmcif_bitset(MASK_MCMD12RBE,
					&host->regs->ce_int_mask);

		time = mmcif_wait_interrupt_flag(host);
		if (time == 0 || host->sd_error != 0)
			return sh_mmcif_error_manage(host);

		sh_mmcif_get_cmd12response(host, cmd);
		return 0;
	}
	if (opc == MMC_CMD_SWITCH)
		mask = MASK_MRBSYE;
	else
		mask = MASK_MCRSPE;

	mask |=	MASK_MCMDVIO | MASK_MBUFVIO | MASK_MWDATERR |
		MASK_MRDATERR | MASK_MRIDXERR | MASK_MRSPERR |
		MASK_MCCSTO | MASK_MCRCSTO | MASK_MWDATTO |
		MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO;

	if (host->data) {
		sh_mmcif_write(0, &host->regs->ce_block_set);
		sh_mmcif_write(data->blocksize, &host->regs->ce_block_set);
	}
	opc = sh_mmcif_set_cmd(host, data, cmd);

	sh_mmcif_write(INT_START_MAGIC, &host->regs->ce_int);
	sh_mmcif_write(mask, &host->regs->ce_int_mask);

	debug("CMD%d ARG:%08x\n", cmd->cmdidx, cmd->cmdarg);
	/* set arg */
	sh_mmcif_write(cmd->cmdarg, &host->regs->ce_arg);
	host->wait_int = 0;
	/* set cmd */
	sh_mmcif_write(opc, &host->regs->ce_cmd_set);

	time = mmcif_wait_interrupt_flag(host);
	if (time == 0)
		return sh_mmcif_error_manage(host);

	if (host->sd_error) {
		switch (cmd->cmdidx) {
		case MMC_CMD_ALL_SEND_CID:
		case MMC_CMD_SELECT_CARD:
		case MMC_CMD_APP_CMD:
			ret = -ETIMEDOUT;
			break;
		default:
			printf(DRIVER_NAME": Cmd(d'%d) err\n", cmd->cmdidx);
			ret = sh_mmcif_error_manage(host);
			break;
		}
		host->sd_error = 0;
		host->wait_int = 0;
		return ret;
	}

	/* if no response */
	if (!(opc & 0x00C00000))
		return 0;

	if (host->wait_int == 1) {
		sh_mmcif_get_response(host, cmd);
		host->wait_int = 0;
	}
	if (host->data)
		ret = sh_mmcif_data_trans(host, data, cmd->cmdidx);
	host->last_cmd = cmd->cmdidx;

	return ret;
}

static int sh_mmcif_send_cmd_common(struct sh_mmcif_host *host,
				    struct mmc_cmd *cmd, struct mmc_data *data)
{
	int ret;

	schedule();

	switch (cmd->cmdidx) {
	case MMC_CMD_APP_CMD:
		return -ETIMEDOUT;
	case MMC_CMD_SEND_EXT_CSD: /* = SD_SEND_IF_COND (8) */
		if (data)
			/* ext_csd */
			break;
		else
			/* send_if_cond cmd (not support) */
			return -ETIMEDOUT;
	default:
		break;
	}
	host->sd_error = 0;
	host->data = data;
	ret = sh_mmcif_start_cmd(host, data, cmd);
	host->data = NULL;

	return ret;
}

static int sh_mmcif_set_ios_common(struct sh_mmcif_host *host, struct mmc *mmc)
{
	if (mmc->clock)
		sh_mmcif_clock_control(host, mmc->clock);

	if (mmc->bus_width == 8)
		host->bus_width = MMC_BUS_WIDTH_8;
	else if (mmc->bus_width == 4)
		host->bus_width = MMC_BUS_WIDTH_4;
	else
		host->bus_width = MMC_BUS_WIDTH_1;

	debug("clock = %d, buswidth = %d\n", mmc->clock, mmc->bus_width);

	return 0;
}

static int sh_mmcif_initialize_common(struct sh_mmcif_host *host)
{
	sh_mmcif_sync_reset(host);
	sh_mmcif_write(MASK_ALL, &host->regs->ce_int_mask);
	return 0;
}

#ifndef CONFIG_DM_MMC
static void *mmc_priv(struct mmc *mmc)
{
	return (void *)mmc->priv;
}

static int sh_mmcif_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
			    struct mmc_data *data)
{
	struct sh_mmcif_host *host = mmc_priv(mmc);

	return sh_mmcif_send_cmd_common(host, cmd, data);
}

static int sh_mmcif_set_ios(struct mmc *mmc)
{
	struct sh_mmcif_host *host = mmc_priv(mmc);

	return sh_mmcif_set_ios_common(host, mmc);
}

static int sh_mmcif_initialize(struct mmc *mmc)
{
	struct sh_mmcif_host *host = mmc_priv(mmc);

	return sh_mmcif_initialize_common(host);
}

static const struct mmc_ops sh_mmcif_ops = {
	.send_cmd       = sh_mmcif_send_cmd,
	.set_ios        = sh_mmcif_set_ios,
	.init           = sh_mmcif_initialize,
};

static struct mmc_config sh_mmcif_cfg = {
	.name		= DRIVER_NAME,
	.ops		= &sh_mmcif_ops,
	.host_caps	= MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT |
			  MMC_MODE_8BIT,
	.voltages	= MMC_VDD_32_33 | MMC_VDD_33_34,
	.b_max		= CONFIG_SYS_MMC_MAX_BLK_COUNT,
};

int mmcif_mmc_init(void)
{
	struct mmc *mmc;
	struct sh_mmcif_host *host = NULL;

	host = malloc(sizeof(struct sh_mmcif_host));
	if (!host)
		return -ENOMEM;
	memset(host, 0, sizeof(*host));

	host->regs = (struct sh_mmcif_regs *)CONFIG_SH_MMCIF_ADDR;
	host->clk = CONFIG_SH_MMCIF_CLK;

	sh_mmcif_cfg.f_min = MMC_CLK_DIV_MIN(host->clk);
	sh_mmcif_cfg.f_max = MMC_CLK_DIV_MAX(host->clk);

	mmc = mmc_create(&sh_mmcif_cfg, host);
	if (mmc == NULL) {
		free(host);
		return -ENOMEM;
	}

	return 0;
}

#else
struct sh_mmcif_plat {
	struct mmc_config cfg;
	struct mmc mmc;
};

int sh_mmcif_dm_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
			struct mmc_data *data)
{
	struct sh_mmcif_host *host = dev_get_priv(dev);

	return sh_mmcif_send_cmd_common(host, cmd, data);
}

int sh_mmcif_dm_set_ios(struct udevice *dev)
{
	struct sh_mmcif_host *host = dev_get_priv(dev);
	struct mmc *mmc = mmc_get_mmc_dev(dev);

	return sh_mmcif_set_ios_common(host, mmc);
}

static const struct dm_mmc_ops sh_mmcif_dm_ops = {
	.send_cmd	= sh_mmcif_dm_send_cmd,
	.set_ios	= sh_mmcif_dm_set_ios,
};

static int sh_mmcif_dm_bind(struct udevice *dev)
{
	struct sh_mmcif_plat *plat = dev_get_plat(dev);

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

static int sh_mmcif_dm_probe(struct udevice *dev)
{
	struct sh_mmcif_plat *plat = dev_get_plat(dev);
	struct sh_mmcif_host *host = dev_get_priv(dev);
	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
	struct clk sh_mmcif_clk;
	fdt_addr_t base;
	int ret;

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

	host->regs = (struct sh_mmcif_regs *)devm_ioremap(dev, base, SZ_2K);
	if (!host->regs)
		return -ENOMEM;

	ret = clk_get_by_index(dev, 0, &sh_mmcif_clk);
	if (ret) {
		debug("failed to get clock, ret=%d\n", ret);
		return ret;
	}

	ret = clk_enable(&sh_mmcif_clk);
	if (ret) {
		debug("failed to enable clock, ret=%d\n", ret);
		return ret;
	}

	host->clk = clk_set_rate(&sh_mmcif_clk, 97500000);

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

	switch (fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "bus-width",
			       1)) {
	case 8:
		plat->cfg.host_caps |= MMC_MODE_8BIT;
		break;
	case 4:
		plat->cfg.host_caps |= MMC_MODE_4BIT;
		break;
	case 1:
		break;
	default:
		dev_err(dev, "Invalid \"bus-width\" value\n");
		return -EINVAL;
	}

	sh_mmcif_initialize_common(host);

	plat->cfg.voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34;
	plat->cfg.f_min = MMC_CLK_DIV_MIN(host->clk);
	plat->cfg.f_max = MMC_CLK_DIV_MAX(host->clk);
	plat->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;

	upriv->mmc = &plat->mmc;

	return 0;
}

static const struct udevice_id sh_mmcif_sd_match[] = {
	{ .compatible = "renesas,sh-mmcif" },
	{ /* sentinel */ }
};

U_BOOT_DRIVER(sh_mmcif_mmc) = {
	.name			= "sh-mmcif",
	.id			= UCLASS_MMC,
	.of_match		= sh_mmcif_sd_match,
	.bind			= sh_mmcif_dm_bind,
	.probe			= sh_mmcif_dm_probe,
	.priv_auto	= sizeof(struct sh_mmcif_host),
	.plat_auto	= sizeof(struct sh_mmcif_plat),
	.ops			= &sh_mmcif_dm_ops,
};
#endif
