/*
 * (C) Copyright 2003
 * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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 <mmc.h>
#include <asm/errno.h>
#include <asm/arch/hardware.h>
#include <part.h>

#ifdef CONFIG_MMC

extern int
fat_register_device(block_dev_desc_t *dev_desc, int part_no);

static block_dev_desc_t mmc_dev;

block_dev_desc_t * mmc_get_dev(int dev)
{
	return ((block_dev_desc_t *)&mmc_dev);
}

/*
 * FIXME needs to read cid and csd info to determine block size
 * and other parameters
 */
static uchar mmc_buf[MMC_BLOCK_SIZE];
static mmc_csd_t mmc_csd;
static int mmc_ready = 0;


static uchar *
/****************************************************/
mmc_cmd(ushort cmd, ushort argh, ushort argl, ushort cmdat)
/****************************************************/
{
	static uchar resp[20];
	ulong status;
	int words, i;

	debug("mmc_cmd %x %x %x %x\n", cmd, argh, argl, cmdat);
	MMC_STRPCL = MMC_STRPCL_STOP_CLK;
	MMC_I_MASK = ~MMC_I_MASK_CLK_IS_OFF;
	while (!(MMC_I_REG & MMC_I_REG_CLK_IS_OFF));
	MMC_CMD    = cmd;
	MMC_ARGH   = argh;
	MMC_ARGL   = argl;
	MMC_CMDAT  = cmdat;
	MMC_I_MASK = ~MMC_I_MASK_END_CMD_RES;
	MMC_STRPCL = MMC_STRPCL_START_CLK;
	while (!(MMC_I_REG & MMC_I_REG_END_CMD_RES));

	status = MMC_STAT;
	debug("MMC status %x\n", status);
	if (status & MMC_STAT_TIME_OUT_RESPONSE) {
		return 0;
	}

	switch (cmdat & 0x3) {
		case MMC_CMDAT_R1:
		case MMC_CMDAT_R3:
			words = 3;
			break;

		case MMC_CMDAT_R2:
			words = 8;
			break;

		default:
			return 0;
	}
	for (i = words-1; i >= 0; i--) {
		ulong res_fifo = MMC_RES;
		int offset = i << 1;

		resp[offset] = ((uchar *)&res_fifo)[0];
		resp[offset+1] = ((uchar *)&res_fifo)[1];
	}
#ifdef MMC_DEBUG
	for (i=0; i<words*2; i += 2) {
		printf("MMC resp[%d] = %02x\n", i, resp[i]);
		printf("MMC resp[%d] = %02x\n", i+1, resp[i+1]);
	}
#endif
	return resp;
}

int
/****************************************************/
mmc_block_read(uchar *dst, ulong src, ulong len)
/****************************************************/
{
	uchar *resp;
	ushort argh, argl;
	ulong status;

	if (len == 0) {
		return 0;
	}

	debug("mmc_block_rd dst %lx src %lx len %d\n", (ulong)dst, src, len);

	argh = len >> 16;
	argl = len & 0xffff;

	/* set block len */
	resp = mmc_cmd(MMC_CMD_SET_BLOCKLEN, argh, argl, MMC_CMDAT_R1);

	/* send read command */
	argh = src >> 16;
	argl = src & 0xffff;
	MMC_STRPCL = MMC_STRPCL_STOP_CLK;
	MMC_RDTO = 0xffff;
	MMC_NOB = 1;
	MMC_BLKLEN = len;
	resp = mmc_cmd(MMC_CMD_READ_BLOCK, argh, argl,
			MMC_CMDAT_R1|MMC_CMDAT_READ|MMC_CMDAT_BLOCK|MMC_CMDAT_DATA_EN);


	MMC_I_MASK = ~MMC_I_MASK_RXFIFO_RD_REQ;
	while (len) {
		if (MMC_I_REG & MMC_I_REG_RXFIFO_RD_REQ) {
#ifdef CONFIG_PXA27X
			int i;
			for (i=min(len,32); i; i--) {
				*dst++ = * ((volatile uchar *) &MMC_RXFIFO);
				len--;
			}
#else
			*dst++ = MMC_RXFIFO;
			len--;
#endif
		}
		status = MMC_STAT;
		if (status & MMC_STAT_ERRORS) {
			printf("MMC_STAT error %lx\n", status);
			return -1;
		}
	}
	MMC_I_MASK = ~MMC_I_MASK_DATA_TRAN_DONE;
	while (!(MMC_I_REG & MMC_I_REG_DATA_TRAN_DONE));
	status = MMC_STAT;
	if (status & MMC_STAT_ERRORS) {
		printf("MMC_STAT error %lx\n", status);
		return -1;
	}
	return 0;
}

int
/****************************************************/
mmc_block_write(ulong dst, uchar *src, int len)
/****************************************************/
{
	uchar *resp;
	ushort argh, argl;
	ulong status;

	if (len == 0) {
		return 0;
	}

	debug("mmc_block_wr dst %lx src %lx len %d\n", dst, (ulong)src, len);

	argh = len >> 16;
	argl = len & 0xffff;

	/* set block len */
	resp = mmc_cmd(MMC_CMD_SET_BLOCKLEN, argh, argl, MMC_CMDAT_R1);

	/* send write command */
	argh = dst >> 16;
	argl = dst & 0xffff;
	MMC_STRPCL = MMC_STRPCL_STOP_CLK;
	MMC_NOB = 1;
	MMC_BLKLEN = len;
	resp = mmc_cmd(MMC_CMD_WRITE_BLOCK, argh, argl,
			MMC_CMDAT_R1|MMC_CMDAT_WRITE|MMC_CMDAT_BLOCK|MMC_CMDAT_DATA_EN);

	MMC_I_MASK = ~MMC_I_MASK_TXFIFO_WR_REQ;
	while (len) {
		if (MMC_I_REG & MMC_I_REG_TXFIFO_WR_REQ) {
			int i, bytes = min(32,len);

			for (i=0; i<bytes; i++) {
				MMC_TXFIFO = *src++;
			}
			if (bytes < 32) {
				MMC_PRTBUF = MMC_PRTBUF_BUF_PART_FULL;
			}
			len -= bytes;
		}
		status = MMC_STAT;
		if (status & MMC_STAT_ERRORS) {
			printf("MMC_STAT error %lx\n", status);
			return -1;
		}
	}
	MMC_I_MASK = ~MMC_I_MASK_DATA_TRAN_DONE;
	while (!(MMC_I_REG & MMC_I_REG_DATA_TRAN_DONE));
	MMC_I_MASK = ~MMC_I_MASK_PRG_DONE;
	while (!(MMC_I_REG & MMC_I_REG_PRG_DONE));
	status = MMC_STAT;
	if (status & MMC_STAT_ERRORS) {
		printf("MMC_STAT error %lx\n", status);
		return -1;
	}
	return 0;
}


int
/****************************************************/
mmc_read(ulong src, uchar *dst, int size)
/****************************************************/
{
	ulong end, part_start, part_end, part_len, aligned_start, aligned_end;
	ulong mmc_block_size, mmc_block_address;

	if (size == 0) {
		return 0;
	}

	if (!mmc_ready) {
		printf("Please initial the MMC first\n");
		return -1;
	}

	mmc_block_size = MMC_BLOCK_SIZE;
	mmc_block_address = ~(mmc_block_size - 1);

	src -= CFG_MMC_BASE;
	end = src + size;
	part_start = ~mmc_block_address & src;
	part_end = ~mmc_block_address & end;
	aligned_start = mmc_block_address & src;
	aligned_end = mmc_block_address & end;

	/* all block aligned accesses */
	debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
	src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
	if (part_start) {
		part_len = mmc_block_size - part_start;
		debug("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
		src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
		if ((mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0) {
			return -1;
		}
		memcpy(dst, mmc_buf+part_start, part_len);
		dst += part_len;
		src += part_len;
	}
	debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
	src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
	for (; src < aligned_end; src += mmc_block_size, dst += mmc_block_size) {
		debug("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
		src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
		if ((mmc_block_read((uchar *)(dst), src, mmc_block_size)) < 0) {
			return -1;
		}
	}
	debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
	src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
	if (part_end && src < end) {
		debug("pe src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
		src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
		if ((mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0) {
			return -1;
		}
		memcpy(dst, mmc_buf, part_end);
	}
	return 0;
}

int
/****************************************************/
mmc_write(uchar *src, ulong dst, int size)
/****************************************************/
{
	ulong end, part_start, part_end, part_len, aligned_start, aligned_end;
	ulong mmc_block_size, mmc_block_address;

	if (size == 0) {
		return 0;
	}

	if (!mmc_ready) {
		printf("Please initial the MMC first\n");
		return -1;
	}

	mmc_block_size = MMC_BLOCK_SIZE;
	mmc_block_address = ~(mmc_block_size - 1);

	dst -= CFG_MMC_BASE;
	end = dst + size;
	part_start = ~mmc_block_address & dst;
	part_end = ~mmc_block_address & end;
	aligned_start = mmc_block_address & dst;
	aligned_end = mmc_block_address & end;

	/* all block aligned accesses */
	debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
	src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
	if (part_start) {
		part_len = mmc_block_size - part_start;
		debug("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
		(ulong)src, dst, end, part_start, part_end, aligned_start, aligned_end);
		if ((mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0) {
			return -1;
		}
		memcpy(mmc_buf+part_start, src, part_len);
		if ((mmc_block_write(aligned_start, mmc_buf, mmc_block_size)) < 0) {
			return -1;
		}
		dst += part_len;
		src += part_len;
	}
	debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
	src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
	for (; dst < aligned_end; src += mmc_block_size, dst += mmc_block_size) {
		debug("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
		src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
		if ((mmc_block_write(dst, (uchar *)src, mmc_block_size)) < 0) {
			return -1;
		}
	}
	debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
	src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
	if (part_end && dst < end) {
		debug("pe src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
		src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
		if ((mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0) {
			return -1;
		}
		memcpy(mmc_buf, src, part_end);
		if ((mmc_block_write(aligned_end, mmc_buf, mmc_block_size)) < 0) {
			return -1;
		}
	}
	return 0;
}

ulong
/****************************************************/
mmc_bread(int dev_num, ulong blknr, ulong blkcnt, ulong *dst)
/****************************************************/
{
	int mmc_block_size = MMC_BLOCK_SIZE;
	ulong src = blknr * mmc_block_size + CFG_MMC_BASE;

	mmc_read(src, (uchar *)dst, blkcnt*mmc_block_size);
	return blkcnt;
}

int
/****************************************************/
mmc_init(int verbose)
/****************************************************/
{
 	int retries, rc = -ENODEV;
	uchar *resp;

#ifdef CONFIG_LUBBOCK
	set_GPIO_mode( GPIO6_MMCCLK_MD );
	set_GPIO_mode( GPIO8_MMCCS0_MD );
#endif
	CKEN |= CKEN12_MMC; /* enable MMC unit clock */
#if defined(CONFIG_ADSVIX)
	/* turn on the power */
	GPCR(114) = GPIO_bit(114);
	udelay(1000);
#endif

	mmc_csd.c_size = 0;

	MMC_CLKRT  = MMC_CLKRT_0_3125MHZ;
	MMC_RESTO  = MMC_RES_TO_MAX;
	MMC_SPI    = MMC_SPI_DISABLE;

	/* reset */
	retries = 10;
	resp = mmc_cmd(0, 0, 0, 0);
	resp = mmc_cmd(1, 0x00ff, 0xc000, MMC_CMDAT_INIT|MMC_CMDAT_BUSY|MMC_CMDAT_R3);
	while (retries-- && resp && !(resp[4] & 0x80)) {
		debug("resp %x %x\n", resp[0], resp[1]);
#ifdef CONFIG_PXA27X
		udelay(10000);
#else
		udelay(50);
#endif
		resp = mmc_cmd(1, 0x00ff, 0xff00, MMC_CMDAT_BUSY|MMC_CMDAT_R3);
	}

	/* try to get card id */
	resp = mmc_cmd(2, 0, 0, MMC_CMDAT_R2);
	if (resp) {
		/* TODO configure mmc driver depending on card attributes */
		mmc_cid_t *cid = (mmc_cid_t *)resp;
		if (verbose) {
			printf("MMC found. Card desciption is:\n");
			printf("Manufacturer ID = %02x%02x%02x\n",
							cid->id[0], cid->id[1], cid->id[2]);
			printf("HW/FW Revision = %x %x\n",cid->hwrev, cid->fwrev);
			cid->hwrev = cid->fwrev = 0;	/* null terminate string */
			printf("Product Name = %s\n",cid->name);
			printf("Serial Number = %02x%02x%02x\n",
							cid->sn[0], cid->sn[1], cid->sn[2]);
			printf("Month = %d\n",cid->month);
			printf("Year = %d\n",1997 + cid->year);
		}
		/* fill in device description */
		mmc_dev.if_type = IF_TYPE_MMC;
		mmc_dev.part_type = PART_TYPE_DOS;
		mmc_dev.dev = 0;
		mmc_dev.lun = 0;
		mmc_dev.type = 0;
		/* FIXME fill in the correct size (is set to 32MByte) */
		mmc_dev.blksz = 512;
		mmc_dev.lba = 0x10000;
		sprintf(mmc_dev.vendor,"Man %02x%02x%02x Snr %02x%02x%02x",
				cid->id[0], cid->id[1], cid->id[2],
				cid->sn[0], cid->sn[1], cid->sn[2]);
		sprintf(mmc_dev.product,"%s",cid->name);
		sprintf(mmc_dev.revision,"%x %x",cid->hwrev, cid->fwrev);
		mmc_dev.removable = 0;
		mmc_dev.block_read = mmc_bread;

		/* MMC exists, get CSD too */
		resp = mmc_cmd(MMC_CMD_SET_RCA, MMC_DEFAULT_RCA, 0, MMC_CMDAT_R1);
		resp = mmc_cmd(MMC_CMD_SEND_CSD, MMC_DEFAULT_RCA, 0, MMC_CMDAT_R2);
		if (resp) {
			mmc_csd_t *csd = (mmc_csd_t *)resp;
			memcpy(&mmc_csd, csd, sizeof(csd));
			rc = 0;
			mmc_ready = 1;
			/* FIXME add verbose printout for csd */
		}
	}

#ifdef CONFIG_PXA27X
	MMC_CLKRT = 1;	/* 10 MHz - see Intel errata */
#else
	MMC_CLKRT = 0;	/* 20 MHz */
#endif
	resp = mmc_cmd(7, MMC_DEFAULT_RCA, 0, MMC_CMDAT_R1);

	fat_register_device(&mmc_dev,1); /* partitions start counting with 1 */

	return rc;
}

int
mmc_ident(block_dev_desc_t *dev)
{
	return 0;
}

int
mmc2info(ulong addr)
{
	/* FIXME hard codes to 32 MB device */
	if (addr >= CFG_MMC_BASE && addr < CFG_MMC_BASE + 0x02000000) {
		return 1;
	}
	return 0;
}

#endif	/* CONFIG_MMC */
