/*
 * MMCIF driver.
 *
 * Copyright (C)  2011 Renesas Solutions Corp.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License.
 */

#include <config.h>
#include <common.h>
#include <watchdog.h>
#include <command.h>
#include <mmc.h>
#include <malloc.h>
#include <asm/errno.h>
#include <asm/io.h>
#include "sh_mmcif.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 = TIMEOUT;
	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);

		WATCHDOG_RESET();
	}
	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);

		WATCHDOG_RESET();
	}
	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 = TIMEOUT;
			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_request(struct mmc *mmc, struct mmc_cmd *cmd,
			    struct mmc_data *data)
{
	struct sh_mmcif_host *host = mmc->priv;
	int ret;

	WATCHDOG_RESET();

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

	return ret;
}

static void sh_mmcif_set_ios(struct mmc *mmc)
{
	struct sh_mmcif_host *host = mmc->priv;

	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);
}

static int sh_mmcif_init(struct mmc *mmc)
{
	struct sh_mmcif_host *host = mmc->priv;

	sh_mmcif_sync_reset(host);
	sh_mmcif_write(MASK_ALL, &host->regs->ce_int_mask);
	return 0;
}

static const struct mmc_ops sh_mmcif_ops = {
	.send_cmd	= sh_mmcif_request,
	.set_ios	= sh_mmcif_set_ios,
	.init		= sh_mmcif_init,
};

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 | MMC_MODE_HC,
	.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;
}
