/*
 * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com>
 *
 * Loosely based on the old code and Linux's PXA MMC driver
 *
 * 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, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <config.h>
#include <common.h>
#include <malloc.h>

#include <mmc.h>
#include <asm/errno.h>
#include <asm/arch/hardware.h>
#include <asm/arch/regs-mmc.h>
#include <asm/io.h>

/* PXAMMC Generic default config for various CPUs */
#if defined(CONFIG_PXA250)
#define PXAMMC_FIFO_SIZE	1
#define PXAMMC_MIN_SPEED	312500
#define PXAMMC_MAX_SPEED	20000000
#define PXAMMC_HOST_CAPS	(0)
#elif defined(CONFIG_PXA27X)
#define PXAMMC_CRC_SKIP
#define PXAMMC_FIFO_SIZE	32
#define PXAMMC_MIN_SPEED	304000
#define PXAMMC_MAX_SPEED	19500000
#define PXAMMC_HOST_CAPS	(MMC_MODE_4BIT)
#elif defined(CONFIG_CPU_MONAHANS)
#define PXAMMC_FIFO_SIZE	32
#define PXAMMC_MIN_SPEED	304000
#define PXAMMC_MAX_SPEED	26000000
#define PXAMMC_HOST_CAPS	(MMC_MODE_4BIT | MMC_MODE_HS)
#else
#error "This CPU isn't supported by PXA MMC!"
#endif

#define MMC_STAT_ERRORS							\
	(MMC_STAT_RES_CRC_ERROR | MMC_STAT_SPI_READ_ERROR_TOKEN |	\
	MMC_STAT_CRC_READ_ERROR | MMC_STAT_TIME_OUT_RESPONSE |		\
	MMC_STAT_READ_TIME_OUT | MMC_STAT_CRC_WRITE_ERROR)

/* 1 millisecond (in wait cycles below it's 100 x 10uS waits) */
#define PXA_MMC_TIMEOUT	100

struct pxa_mmc_priv {
	struct pxa_mmc_regs *regs;
};

/* Wait for bit to be set */
static int pxa_mmc_wait(struct mmc *mmc, uint32_t mask)
{
	struct pxa_mmc_priv *priv = (struct pxa_mmc_priv *)mmc->priv;
	struct pxa_mmc_regs *regs = priv->regs;
	unsigned int timeout = PXA_MMC_TIMEOUT;

	/* Wait for bit to be set */
	while (--timeout) {
		if (readl(&regs->stat) & mask)
			break;
		udelay(10);
	}

	if (!timeout)
		return -ETIMEDOUT;

	return 0;
}

static int pxa_mmc_stop_clock(struct mmc *mmc)
{
	struct pxa_mmc_priv *priv = (struct pxa_mmc_priv *)mmc->priv;
	struct pxa_mmc_regs *regs = priv->regs;
	unsigned int timeout = PXA_MMC_TIMEOUT;

	/* If the clock aren't running, exit */
	if (!(readl(&regs->stat) & MMC_STAT_CLK_EN))
		return 0;

	/* Tell the controller to turn off the clock */
	writel(MMC_STRPCL_STOP_CLK, &regs->strpcl);

	/* Wait until the clock are off */
	while (--timeout) {
		if (!(readl(&regs->stat) & MMC_STAT_CLK_EN))
			break;
		udelay(10);
	}

	/* The clock refused to stop, scream and die a painful death */
	if (!timeout)
		return -ETIMEDOUT;

	/* The clock stopped correctly */
	return 0;
}

static int pxa_mmc_start_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
				uint32_t cmdat)
{
	struct pxa_mmc_priv *priv = (struct pxa_mmc_priv *)mmc->priv;
	struct pxa_mmc_regs *regs = priv->regs;
	int ret;

	/* The card can send a "busy" response */
	if (cmd->flags & MMC_RSP_BUSY)
		cmdat |= MMC_CMDAT_BUSY;

	/* Inform the controller about response type */
	switch (cmd->resp_type) {
	case MMC_RSP_R1:
	case MMC_RSP_R1b:
		cmdat |= MMC_CMDAT_R1;
		break;
	case MMC_RSP_R2:
		cmdat |= MMC_CMDAT_R2;
		break;
	case MMC_RSP_R3:
		cmdat |= MMC_CMDAT_R3;
		break;
	default:
		break;
	}

	/* Load command and it's arguments into the controller */
	writel(cmd->cmdidx, &regs->cmd);
	writel(cmd->cmdarg >> 16, &regs->argh);
	writel(cmd->cmdarg & 0xffff, &regs->argl);
	writel(cmdat, &regs->cmdat);

	/* Start the controller clock and wait until they are started */
	writel(MMC_STRPCL_START_CLK, &regs->strpcl);

	ret = pxa_mmc_wait(mmc, MMC_STAT_CLK_EN);
	if (ret)
		return ret;

	/* Correct and happy end */
	return 0;
}

static int pxa_mmc_cmd_done(struct mmc *mmc, struct mmc_cmd *cmd)
{
	struct pxa_mmc_priv *priv = (struct pxa_mmc_priv *)mmc->priv;
	struct pxa_mmc_regs *regs = priv->regs;
	uint32_t a, b, c;
	int i;
	int stat;

	/* Read the controller status */
	stat = readl(&regs->stat);

	/*
	 * Linux says:
	 * Did I mention this is Sick.  We always need to
	 * discard the upper 8 bits of the first 16-bit word.
	 */
	a = readl(&regs->res) & 0xffff;
	for (i = 0; i < 4; i++) {
		b = readl(&regs->res) & 0xffff;
		c = readl(&regs->res) & 0xffff;
		cmd->response[i] = (a << 24) | (b << 8) | (c >> 8);
		a = c;
	}

	/* The command response didn't arrive */
	if (stat & MMC_STAT_TIME_OUT_RESPONSE)
		return -ETIMEDOUT;
	else if (stat & MMC_STAT_RES_CRC_ERROR && cmd->flags & MMC_RSP_CRC) {
#ifdef	PXAMMC_CRC_SKIP
		if (cmd->flags & MMC_RSP_136 && cmd->response[0] & (1 << 31))
			printf("Ignoring CRC, this may be dangerous!\n");
		else
#endif
		return -EILSEQ;
	}

	/* The command response was successfully read */
	return 0;
}

static int pxa_mmc_do_read_xfer(struct mmc *mmc, struct mmc_data *data)
{
	struct pxa_mmc_priv *priv = (struct pxa_mmc_priv *)mmc->priv;
	struct pxa_mmc_regs *regs = priv->regs;
	uint32_t len;
	uint32_t *buf = (uint32_t *)data->dest;
	int size;
	int ret;

	len = data->blocks * data->blocksize;

	while (len) {
		/* The controller has data ready */
		if (readl(&regs->i_reg) & MMC_I_REG_RXFIFO_RD_REQ) {
			size = min(len, PXAMMC_FIFO_SIZE);
			len -= size;
			size /= 4;

			/* Read data into the buffer */
			while (size--)
				*buf++ = readl(&regs->rxfifo);

		}

		if (readl(&regs->stat) & MMC_STAT_ERRORS)
			return -EIO;
	}

	/* Wait for the transmission-done interrupt */
	ret = pxa_mmc_wait(mmc, MMC_STAT_DATA_TRAN_DONE);
	if (ret)
		return ret;

	return 0;
}

static int pxa_mmc_do_write_xfer(struct mmc *mmc, struct mmc_data *data)
{
	struct pxa_mmc_priv *priv = (struct pxa_mmc_priv *)mmc->priv;
	struct pxa_mmc_regs *regs = priv->regs;
	uint32_t len;
	uint32_t *buf = (uint32_t *)data->src;
	int size;
	int ret;

	len = data->blocks * data->blocksize;

	while (len) {
		/* The controller is ready to receive data */
		if (readl(&regs->i_reg) & MMC_I_REG_TXFIFO_WR_REQ) {
			size = min(len, PXAMMC_FIFO_SIZE);
			len -= size;
			size /= 4;

			while (size--)
				writel(*buf++, &regs->txfifo);

			if (min(len, PXAMMC_FIFO_SIZE) < 32)
				writel(MMC_PRTBUF_BUF_PART_FULL, &regs->prtbuf);
		}

		if (readl(&regs->stat) & MMC_STAT_ERRORS)
			return -EIO;
	}

	/* Wait for the transmission-done interrupt */
	ret = pxa_mmc_wait(mmc, MMC_STAT_DATA_TRAN_DONE);
	if (ret)
		return ret;

	/* Wait until the data are really written to the card */
	ret = pxa_mmc_wait(mmc, MMC_STAT_PRG_DONE);
	if (ret)
		return ret;

	return 0;
}

static int pxa_mmc_request(struct mmc *mmc, struct mmc_cmd *cmd,
				struct mmc_data *data)
{
	struct pxa_mmc_priv *priv = (struct pxa_mmc_priv *)mmc->priv;
	struct pxa_mmc_regs *regs = priv->regs;
	uint32_t cmdat = 0;
	int ret;

	/* Stop the controller */
	ret = pxa_mmc_stop_clock(mmc);
	if (ret)
		return ret;

	/* If we're doing data transfer, configure the controller accordingly */
	if (data) {
		writel(data->blocks, &regs->nob);
		writel(data->blocksize, &regs->blklen);
		/* This delay can be optimized, but stick with max value */
		writel(0xffff, &regs->rdto);
		cmdat |= MMC_CMDAT_DATA_EN;
		if (data->flags & MMC_DATA_WRITE)
			cmdat |= MMC_CMDAT_WRITE;
	}

	/* Run in 4bit mode if the card can do it */
	if (mmc->bus_width == 4)
		cmdat |= MMC_CMDAT_SD_4DAT;

	/* Execute the command */
	ret = pxa_mmc_start_cmd(mmc, cmd, cmdat);
	if (ret)
		return ret;

	/* Wait until the command completes */
	ret = pxa_mmc_wait(mmc, MMC_STAT_END_CMD_RES);
	if (ret)
		return ret;

	/* Read back the result */
	ret = pxa_mmc_cmd_done(mmc, cmd);
	if (ret)
		return ret;

	/* In case there was a data transfer scheduled, do it */
	if (data) {
		if (data->flags & MMC_DATA_WRITE)
			pxa_mmc_do_write_xfer(mmc, data);
		else
			pxa_mmc_do_read_xfer(mmc, data);
	}

	return 0;
}

static void pxa_mmc_set_ios(struct mmc *mmc)
{
	struct pxa_mmc_priv *priv = (struct pxa_mmc_priv *)mmc->priv;
	struct pxa_mmc_regs *regs = priv->regs;
	uint32_t tmp;
	uint32_t pxa_mmc_clock;

	if (!mmc->clock) {
		pxa_mmc_stop_clock(mmc);
		return;
	}

	/* PXA3xx can do 26MHz with special settings. */
	if (mmc->clock == 26000000) {
		writel(0x7, &regs->clkrt);
		return;
	}

	/* Set clock to the card the usual way. */
	pxa_mmc_clock = 0;
	tmp = mmc->f_max / mmc->clock;
	tmp += tmp % 2;

	while (tmp > 1) {
		pxa_mmc_clock++;
		tmp >>= 1;
	}

	writel(pxa_mmc_clock, &regs->clkrt);
}

static int pxa_mmc_init(struct mmc *mmc)
{
	struct pxa_mmc_priv *priv = (struct pxa_mmc_priv *)mmc->priv;
	struct pxa_mmc_regs *regs = priv->regs;

	/* Make sure the clock are stopped */
	pxa_mmc_stop_clock(mmc);

	/* Turn off SPI mode */
	writel(0, &regs->spi);

	/* Set up maximum timeout to wait for command response */
	writel(MMC_RES_TO_MAX_MASK, &regs->resto);

	/* Mask all interrupts */
	writel(~(MMC_I_MASK_TXFIFO_WR_REQ | MMC_I_MASK_RXFIFO_RD_REQ),
		&regs->i_mask);
	return 0;
}

int pxa_mmc_register(int card_index)
{
	struct mmc *mmc;
	struct pxa_mmc_priv *priv;
	uint32_t reg;
	int ret = -ENOMEM;

	mmc = malloc(sizeof(struct mmc));
	if (!mmc)
		goto err0;

	priv = malloc(sizeof(struct pxa_mmc_priv));
	if (!priv)
		goto err1;

	switch (card_index) {
	case 0:
		priv->regs = (struct pxa_mmc_regs *)MMC0_BASE;
		break;
	case 1:
		priv->regs = (struct pxa_mmc_regs *)MMC1_BASE;
		break;
	default:
		printf("PXA MMC: Invalid MMC controller ID (card_index = %d)\n",
			card_index);
		goto err2;
	}

	mmc->priv = priv;

	sprintf(mmc->name, "PXA MMC");
	mmc->send_cmd	= pxa_mmc_request;
	mmc->set_ios	= pxa_mmc_set_ios;
	mmc->init	= pxa_mmc_init;

	mmc->voltages	= MMC_VDD_32_33 | MMC_VDD_33_34;
	mmc->f_max	= PXAMMC_MAX_SPEED;
	mmc->f_min	= PXAMMC_MIN_SPEED;
	mmc->host_caps	= PXAMMC_HOST_CAPS;

	mmc->b_max = 0;

#ifndef	CONFIG_CPU_MONAHANS	/* PXA2xx */
	reg = readl(CKEN);
	reg |= CKEN12_MMC;
	writel(reg, CKEN);
#else				/* PXA3xx */
	reg = readl(CKENA);
	reg |= CKENA_12_MMC0 | CKENA_13_MMC1;
	writel(reg, CKENA);
#endif

	mmc_register(mmc);

	return 0;

err2:
	free(priv);
err1:
	free(mmc);
err0:
	return ret;
}
