/*
 * Copyright (C) 2010
 * Rob Emanuele <rob@emanuele.us>
 * Reinhard Meyer, EMK Elektronik <reinhard.meyer@emk-elektronik.de>
 *
 * Original Driver:
 * Copyright (C) 2004-2006 Atmel Corporation
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <clk.h>
#include <mmc.h>
#include <part.h>
#include <malloc.h>
#include <asm/io.h>
#include <linux/errno.h>
#include <asm/byteorder.h>
#include <asm/arch/clk.h>
#include <asm/arch/hardware.h>
#include <dm/device.h>
#include "atmel_mci.h"

DECLARE_GLOBAL_DATA_PTR;

#ifndef CONFIG_SYS_MMC_CLK_OD
# define CONFIG_SYS_MMC_CLK_OD	150000
#endif

#define MMC_DEFAULT_BLKLEN	512

#if defined(CONFIG_ATMEL_MCI_PORTB)
# define MCI_BUS 1
#else
# define MCI_BUS 0
#endif

struct atmel_mci_priv {
	struct mmc_config	cfg;
	struct atmel_mci	*mci;
	unsigned int		initialized:1;
	unsigned int		curr_clk;
#ifdef CONFIG_DM_MMC
	struct mmc	mmc;
	ulong		bus_clk_rate;
#endif
};

/* Read Atmel MCI IP version */
static unsigned int atmel_mci_get_version(struct atmel_mci *mci)
{
	return readl(&mci->version) & 0x00000fff;
}

/*
 * Print command and status:
 *
 * - always when DEBUG is defined
 * - on command errors
 */
static void dump_cmd(u32 cmdr, u32 arg, u32 status, const char* msg)
{
	debug("gen_atmel_mci: CMDR %08x (%2u) ARGR %08x (SR: %08x) %s\n",
	      cmdr, cmdr & 0x3F, arg, status, msg);
}

/* Setup for MCI Clock and Block Size */
#ifdef CONFIG_DM_MMC
static void mci_set_mode(struct atmel_mci_priv *priv, u32 hz, u32 blklen)
{
	struct mmc *mmc = &priv->mmc;
	u32 bus_hz = priv->bus_clk_rate;
#else
static void mci_set_mode(struct mmc *mmc, u32 hz, u32 blklen)
{
	struct atmel_mci_priv *priv = mmc->priv;
	u32 bus_hz = get_mci_clk_rate();
#endif

	atmel_mci_t *mci = priv->mci;
	u32 clkdiv = 255;
	unsigned int version = atmel_mci_get_version(mci);
	u32 clkodd = 0;
	u32 mr;

	debug("mci: bus_hz is %u, setting clock %u Hz, block size %u\n",
		bus_hz, hz, blklen);
	if (hz > 0) {
		if (version >= 0x500) {
			clkdiv = DIV_ROUND_UP(bus_hz, hz) - 2;
			if (clkdiv > 511)
				clkdiv = 511;

			clkodd = clkdiv & 1;
			clkdiv >>= 1;

			debug("mci: setting clock %u Hz, block size %u\n",
			      bus_hz / (clkdiv * 2 + clkodd + 2), blklen);
		} else {
			/* find clkdiv yielding a rate <= than requested */
			for (clkdiv = 0; clkdiv < 255; clkdiv++) {
				if ((bus_hz / (clkdiv + 1) / 2) <= hz)
					break;
			}
			debug("mci: setting clock %u Hz, block size %u\n",
			      (bus_hz / (clkdiv + 1)) / 2, blklen);

		}
	}
	if (version >= 0x500)
		priv->curr_clk = bus_hz / (clkdiv * 2 + clkodd + 2);
	else
		priv->curr_clk = (bus_hz / (clkdiv + 1)) / 2;
	blklen &= 0xfffc;

	mr = MMCI_BF(CLKDIV, clkdiv);

	/* MCI IP version >= 0x200 has R/WPROOF */
	if (version >= 0x200)
		mr |= MMCI_BIT(RDPROOF) | MMCI_BIT(WRPROOF);

	/*
	 * MCI IP version >= 0x500 use bit 16 as clkodd.
	 * MCI IP version < 0x500 use upper 16 bits for blklen.
	 */
	if (version >= 0x500)
		mr |= MMCI_BF(CLKODD, clkodd);
	else
		mr |= MMCI_BF(BLKLEN, blklen);

	writel(mr, &mci->mr);

	/* MCI IP version >= 0x200 has blkr */
	if (version >= 0x200)
		writel(MMCI_BF(BLKLEN, blklen), &mci->blkr);

	if (mmc->card_caps & mmc->cfg->host_caps & MMC_MODE_HS)
		writel(MMCI_BIT(HSMODE), &mci->cfg);

	priv->initialized = 1;
}

/* Return the CMDR with flags for a given command and data packet */
static u32 mci_encode_cmd(
	struct mmc_cmd *cmd, struct mmc_data *data, u32* error_flags)
{
	u32 cmdr = 0;

	/* Default Flags for Errors */
	*error_flags |= (MMCI_BIT(DTOE) | MMCI_BIT(RDIRE) | MMCI_BIT(RENDE) |
		MMCI_BIT(RINDE) | MMCI_BIT(RTOE));

	/* Default Flags for the Command */
	cmdr |= MMCI_BIT(MAXLAT);

	if (data) {
		cmdr |= MMCI_BF(TRCMD, 1);
		if (data->blocks > 1)
			cmdr |= MMCI_BF(TRTYP, 1);
		if (data->flags & MMC_DATA_READ)
			cmdr |= MMCI_BIT(TRDIR);
	}

	if (cmd->resp_type & MMC_RSP_CRC)
		*error_flags |= MMCI_BIT(RCRCE);
	if (cmd->resp_type & MMC_RSP_136)
		cmdr |= MMCI_BF(RSPTYP, 2);
	else if (cmd->resp_type & MMC_RSP_BUSY)
		cmdr |= MMCI_BF(RSPTYP, 3);
	else if (cmd->resp_type & MMC_RSP_PRESENT)
		cmdr |= MMCI_BF(RSPTYP, 1);

	return cmdr | MMCI_BF(CMDNB, cmd->cmdidx);
}

/* Entered into function pointer in mci_send_cmd */
static u32 mci_data_read(atmel_mci_t *mci, u32* data, u32 error_flags)
{
	u32 status;

	do {
		status = readl(&mci->sr);
		if (status & (error_flags | MMCI_BIT(OVRE)))
			goto io_fail;
	} while (!(status & MMCI_BIT(RXRDY)));

	if (status & MMCI_BIT(RXRDY)) {
		*data = readl(&mci->rdr);
		status = 0;
	}
io_fail:
	return status;
}

/* Entered into function pointer in mci_send_cmd */
static u32 mci_data_write(atmel_mci_t *mci, u32* data, u32 error_flags)
{
	u32 status;

	do {
		status = readl(&mci->sr);
		if (status & (error_flags | MMCI_BIT(UNRE)))
			goto io_fail;
	} while (!(status & MMCI_BIT(TXRDY)));

	if (status & MMCI_BIT(TXRDY)) {
		writel(*data, &mci->tdr);
		status = 0;
	}
io_fail:
	return status;
}

/*
 * Entered into mmc structure during driver init
 *
 * Sends a command out on the bus and deals with the block data.
 * Takes the mmc pointer, a command pointer, and an optional data pointer.
 */
#ifdef CONFIG_DM_MMC
static int atmel_mci_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
			      struct mmc_data *data)
{
	struct atmel_mci_priv *priv = dev_get_priv(dev);
	struct mmc *mmc = mmc_get_mmc_dev(dev);
#else
static int
mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
{
	struct atmel_mci_priv *priv = mmc->priv;
#endif
	atmel_mci_t *mci = priv->mci;
	u32 cmdr;
	u32 error_flags = 0;
	u32 status;

	if (!priv->initialized) {
		puts ("MCI not initialized!\n");
		return -ECOMM;
	}

	/* Figure out the transfer arguments */
	cmdr = mci_encode_cmd(cmd, data, &error_flags);

	/* For multi blocks read/write, set the block register */
	if ((cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK)
			|| (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK))
		writel(data->blocks | MMCI_BF(BLKLEN, mmc->read_bl_len),
			&mci->blkr);

	/* Send the command */
	writel(cmd->cmdarg, &mci->argr);
	writel(cmdr, &mci->cmdr);

#ifdef DEBUG
	dump_cmd(cmdr, cmd->cmdarg, 0, "DEBUG");
#endif

	/* Wait for the command to complete */
	while (!((status = readl(&mci->sr)) & MMCI_BIT(CMDRDY)));

	if ((status & error_flags) & MMCI_BIT(RTOE)) {
		dump_cmd(cmdr, cmd->cmdarg, status, "Command Time Out");
		return -ETIMEDOUT;
	} else if (status & error_flags) {
		dump_cmd(cmdr, cmd->cmdarg, status, "Command Failed");
		return -ECOMM;
	}

	/* Copy the response to the response buffer */
	if (cmd->resp_type & MMC_RSP_136) {
		cmd->response[0] = readl(&mci->rspr);
		cmd->response[1] = readl(&mci->rspr1);
		cmd->response[2] = readl(&mci->rspr2);
		cmd->response[3] = readl(&mci->rspr3);
	} else
		cmd->response[0] = readl(&mci->rspr);

	/* transfer all of the blocks */
	if (data) {
		u32 word_count, block_count;
		u32* ioptr;
		u32 sys_blocksize, dummy, i;
		u32 (*mci_data_op)
			(atmel_mci_t *mci, u32* data, u32 error_flags);

		if (data->flags & MMC_DATA_READ) {
			mci_data_op = mci_data_read;
			sys_blocksize = mmc->read_bl_len;
			ioptr = (u32*)data->dest;
		} else {
			mci_data_op = mci_data_write;
			sys_blocksize = mmc->write_bl_len;
			ioptr = (u32*)data->src;
		}

		status = 0;
		for (block_count = 0;
				block_count < data->blocks && !status;
				block_count++) {
			word_count = 0;
			do {
				status = mci_data_op(mci, ioptr, error_flags);
				word_count++;
				ioptr++;
			} while (!status && word_count < (data->blocksize/4));
#ifdef DEBUG
			if (data->flags & MMC_DATA_READ)
			{
				u32 cnt = word_count * 4;
				printf("Read Data:\n");
				print_buffer(0, data->dest + cnt * block_count,
					     1, cnt, 0);
			}
#endif
#ifdef DEBUG
			if (!status && word_count < (sys_blocksize / 4))
				printf("filling rest of block...\n");
#endif
			/* fill the rest of a full block */
			while (!status && word_count < (sys_blocksize / 4)) {
				status = mci_data_op(mci, &dummy,
					error_flags);
				word_count++;
			}
			if (status) {
				dump_cmd(cmdr, cmd->cmdarg, status,
					"Data Transfer Failed");
				return -ECOMM;
			}
		}

		/* Wait for Transfer End */
		i = 0;
		do {
			status = readl(&mci->sr);

			if (status & error_flags) {
				dump_cmd(cmdr, cmd->cmdarg, status,
					"DTIP Wait Failed");
				return -ECOMM;
			}
			i++;
		} while ((status & MMCI_BIT(DTIP)) && i < 10000);
		if (status & MMCI_BIT(DTIP)) {
			dump_cmd(cmdr, cmd->cmdarg, status,
				"XFER DTIP never unset, ignoring");
		}
	}

	/*
	 * After the switch command, wait for 8 clocks before the next
	 * command
	 */
	if (cmd->cmdidx == MMC_CMD_SWITCH)
		udelay(8*1000000 / priv->curr_clk); /* 8 clk in us */

	return 0;
}

#ifdef CONFIG_DM_MMC
static int atmel_mci_set_ios(struct udevice *dev)
{
	struct atmel_mci_priv *priv = dev_get_priv(dev);
	struct mmc *mmc = mmc_get_mmc_dev(dev);
#else
/* Entered into mmc structure during driver init */
static int mci_set_ios(struct mmc *mmc)
{
	struct atmel_mci_priv *priv = mmc->priv;
#endif
	atmel_mci_t *mci = priv->mci;
	int bus_width = mmc->bus_width;
	unsigned int version = atmel_mci_get_version(mci);
	int busw;

	/* Set the clock speed */
#ifdef CONFIG_DM_MMC
	mci_set_mode(priv, mmc->clock, MMC_DEFAULT_BLKLEN);
#else
	mci_set_mode(mmc, mmc->clock, MMC_DEFAULT_BLKLEN);
#endif

	/*
	 * set the bus width and select slot for this interface
	 * there is no capability for multiple slots on the same interface yet
	 */
	if ((version & 0xf00) >= 0x300) {
		switch (bus_width) {
		case 8:
			busw = 3;
			break;
		case 4:
			busw = 2;
			break;
		default:
			busw = 0;
			break;
		}

		writel(busw << 6 | MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr);
	} else {
		busw = (bus_width == 4) ? 1 : 0;

		writel(busw << 7 | MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr);
	}

	return 0;
}

#ifdef CONFIG_DM_MMC
static int atmel_mci_hw_init(struct atmel_mci_priv *priv)
{
#else
/* Entered into mmc structure during driver init */
static int mci_init(struct mmc *mmc)
{
	struct atmel_mci_priv *priv = mmc->priv;
#endif
	atmel_mci_t *mci = priv->mci;

	/* Initialize controller */
	writel(MMCI_BIT(SWRST), &mci->cr);	/* soft reset */
	writel(MMCI_BIT(PWSDIS), &mci->cr);	/* disable power save */
	writel(MMCI_BIT(MCIEN), &mci->cr);	/* enable mci */
	writel(MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr);	/* select port */

	/* This delay can be optimized, but stick with max value */
	writel(0x7f, &mci->dtor);
	/* Disable Interrupts */
	writel(~0UL, &mci->idr);

	/* Set default clocks and blocklen */
#ifdef CONFIG_DM_MMC
	mci_set_mode(priv, CONFIG_SYS_MMC_CLK_OD, MMC_DEFAULT_BLKLEN);
#else
	mci_set_mode(mmc, CONFIG_SYS_MMC_CLK_OD, MMC_DEFAULT_BLKLEN);
#endif

	return 0;
}

#ifndef CONFIG_DM_MMC
static const struct mmc_ops atmel_mci_ops = {
	.send_cmd	= mci_send_cmd,
	.set_ios	= mci_set_ios,
	.init		= mci_init,
};

/*
 * This is the only exported function
 *
 * Call it with the MCI register base address
 */
int atmel_mci_init(void *regs)
{
	struct mmc *mmc;
	struct mmc_config *cfg;
	struct atmel_mci_priv *priv;
	unsigned int version;

	priv = calloc(1, sizeof(*priv));
	if (!priv)
		return -ENOMEM;

	cfg = &priv->cfg;

	cfg->name = "mci";
	cfg->ops = &atmel_mci_ops;

	priv->mci = (struct atmel_mci *)regs;
	priv->initialized = 0;

	/* need to be able to pass these in on a board by board basis */
	cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
	version = atmel_mci_get_version(priv->mci);
	if ((version & 0xf00) >= 0x300) {
		cfg->host_caps = MMC_MODE_8BIT;
		cfg->host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz;
	}

	cfg->host_caps |= MMC_MODE_4BIT;

	/*
	 * min and max frequencies determined by
	 * max and min of clock divider
	 */
	cfg->f_min = get_mci_clk_rate() / (2*256);
	cfg->f_max = get_mci_clk_rate() / (2*1);

	cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;

	mmc = mmc_create(cfg, priv);

	if (mmc == NULL) {
		free(priv);
		return -ENODEV;
	}
	/* NOTE: possibly leaking the priv structure */

	return 0;
}
#endif

#ifdef CONFIG_DM_MMC
static const struct dm_mmc_ops atmel_mci_mmc_ops = {
	.send_cmd = atmel_mci_send_cmd,
	.set_ios = atmel_mci_set_ios,
};

static void atmel_mci_setup_cfg(struct atmel_mci_priv *priv)
{
	struct mmc_config *cfg;
	u32 version;

	cfg = &priv->cfg;
	cfg->name = "Atmel mci";
	cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;

	/*
	 * If the version is above 3.0, the capabilities of the 8-bit
	 * bus width and high speed are supported.
	 */
	version = atmel_mci_get_version(priv->mci);
	if ((version & 0xf00) >= 0x300) {
		cfg->host_caps = MMC_MODE_8BIT |
				 MMC_MODE_HS | MMC_MODE_HS_52MHz;
	}

	cfg->host_caps |= MMC_MODE_4BIT;
	cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
	cfg->f_min = priv->bus_clk_rate / (2 * 256);
	cfg->f_max = priv->bus_clk_rate / 2;
}

static int atmel_mci_enable_clk(struct udevice *dev)
{
	struct atmel_mci_priv *priv = dev_get_priv(dev);
	struct clk clk;
	ulong clk_rate;
	int ret = 0;

	ret = clk_get_by_index(dev, 0, &clk);
	if (ret) {
		ret = -EINVAL;
		goto failed;
	}

	ret = clk_enable(&clk);
	if (ret)
		goto failed;

	clk_rate = clk_get_rate(&clk);
	if (!clk_rate) {
		ret = -EINVAL;
		goto failed;
	}

	priv->bus_clk_rate = clk_rate;

failed:
	clk_free(&clk);

	return ret;
}

static int atmel_mci_probe(struct udevice *dev)
{
	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
	struct atmel_mci_priv *priv = dev_get_priv(dev);
	struct mmc *mmc;
	int ret;

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

	priv->mci = (struct atmel_mci *)dev_get_addr_ptr(dev);

	atmel_mci_setup_cfg(priv);

	mmc = &priv->mmc;
	mmc->cfg = &priv->cfg;
	mmc->dev = dev;
	upriv->mmc = mmc;

	atmel_mci_hw_init(priv);

	return 0;
}

static int atmel_mci_bind(struct udevice *dev)
{
	struct atmel_mci_priv *priv = dev_get_priv(dev);

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

static const struct udevice_id atmel_mci_ids[] = {
	{ .compatible = "atmel,hsmci" },
	{ }
};

U_BOOT_DRIVER(atmel_mci) = {
	.name = "atmel-mci",
	.id = UCLASS_MMC,
	.of_match = atmel_mci_ids,
	.bind = atmel_mci_bind,
	.probe = atmel_mci_probe,
	.priv_auto_alloc_size = sizeof(struct atmel_mci_priv),
	.ops = &atmel_mci_mmc_ops,
};
#endif
