/*
 * (C) Copyright 2004, Psyent Corporation <www.psyent.com>
 * Scott McNutt <smcnutt@psyent.com>
 *
 * 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 <common.h>

#if defined(CFG_NIOS_EPCSBASE)
#include <command.h>
#include <nios2.h>
#include <nios2-io.h>
#include <nios2-epcs.h>


/*-----------------------------------------------------------------------*/
#define SHORT_HELP\
	"epcs    - read/write Cyclone EPCS configuration device.\n"

#define LONG_HELP\
	"\n"\
	"epcs erase start [end]\n"\
	"    - erase sector start or sectors start through end.\n"\
	"epcs info\n"\
	"    - display EPCS device information.\n"\
	"epcs protect on | off\n"\
	"    - turn device protection on or off.\n"\
	"epcs read addr offset count\n"\
	"    - read count bytes from offset to addr.\n"\
	"epcs write addr offset count\n"\
	"    - write count bytes to offset from addr.\n"\
	"epcs verify addr offset count\n"\
	"    - verify count bytes at offset from addr.\n"


/*-----------------------------------------------------------------------*/
/* Operation codes for serial configuration devices
 */
#define EPCS_WRITE_ENA		0x06	/* Write enable */
#define EPCS_WRITE_DIS		0x04	/* Write disable */
#define EPCS_READ_STAT		0x05	/* Read status */
#define EPCS_READ_BYTES		0x03	/* Read bytes */
#define EPCS_READ_ID		0xab	/* Read silicon id */
#define EPCS_WRITE_STAT		0x01	/* Write status */
#define EPCS_WRITE_BYTES	0x02	/* Write bytes */
#define EPCS_ERASE_BULK		0xc7	/* Erase entire device */
#define EPCS_ERASE_SECT		0xd8	/* Erase sector */

/* Device status register bits
 */
#define EPCS_STATUS_WIP		(1<<0)	/* Write in progress */
#define EPCS_STATUS_WEL		(1<<1)	/* Write enable latch */

/* Misc
 */
#define EPCS_TIMEOUT		100	/* 100 msec timeout */

static nios_spi_t *epcs =
	(nios_spi_t *)CACHE_BYPASS(CFG_NIOS_EPCSBASE);

/***********************************************************************
 * Device access
 ***********************************************************************/
static int epcs_cs (int assert)
{
	ulong start;

	if (assert) {
		epcs->control |= NIOS_SPI_SSO;
	} else {
		/* Let all bits shift out */
		start = get_timer (0);
		while ((epcs->status & NIOS_SPI_TMT) == 0)
			if (get_timer (start) > EPCS_TIMEOUT)
				return (-1);
		epcs->control &= ~NIOS_SPI_SSO;
	}
	return (0);
}

static int epcs_tx (unsigned char c)
{
	ulong start;

	start = get_timer (0);
	while ((epcs->status & NIOS_SPI_TRDY) == 0)
		if (get_timer (start) > EPCS_TIMEOUT)
			return (-1);
	epcs->txdata = c;
	return (0);
}

static int epcs_rx (void)
{
	ulong start;

	start = get_timer (0);
	while ((epcs->status & NIOS_SPI_RRDY) == 0)
		if (get_timer (start) > EPCS_TIMEOUT)
			return (-1);
	return (epcs->rxdata);
}

static unsigned char bitrev[] = {
	0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e,
	0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f
};

static unsigned char epcs_bitrev (unsigned char c)
{
	unsigned char val;

	val  = bitrev[c>>4];
	val |= bitrev[c & 0x0f]<<4;
	return (val);
}

static void epcs_rcv (unsigned char *dst, int len)
{
	while (len--) {
		epcs_tx (0);
		*dst++ = epcs_rx ();
	}
}

static void epcs_rrcv (unsigned char *dst, int len)
{
	while (len--) {
		epcs_tx (0);
		*dst++ = epcs_bitrev (epcs_rx ());
	}
}

static void epcs_snd (unsigned char *src, int len)
{
	while (len--) {
		epcs_tx (*src++);
		epcs_rx ();
	}
}

static void epcs_rsnd (unsigned char *src, int len)
{
	while (len--) {
		epcs_tx (epcs_bitrev (*src++));
		epcs_rx ();
	}
}

static void epcs_wr_enable (void)
{
	epcs_cs (1);
	epcs_tx (EPCS_WRITE_ENA);
	epcs_rx ();
	epcs_cs (0);
}

static unsigned char epcs_status_rd (void)
{
	unsigned char status;

	epcs_cs (1);
	epcs_tx (EPCS_READ_STAT);
	epcs_rx ();
	epcs_tx (0);
	status = epcs_rx ();
	epcs_cs (0);
	return (status);
}

static void epcs_status_wr (unsigned char status)
{
	epcs_wr_enable ();
	epcs_cs (1);
	epcs_tx (EPCS_WRITE_STAT);
	epcs_rx ();
	epcs_tx (status);
	epcs_rx ();
	epcs_cs (0);
	return;
}

/***********************************************************************
 * Device information
 ***********************************************************************/

static struct epcs_devinfo_t devinfo[] = {
	{ "EPCS1 ", 0x10, 17, 4, 15, 8, 0x0c },
	{ "EPCS4 ", 0x12, 19, 8, 16, 8, 0x1c },
	{ 0, 0, 0, 0, 0, 0 }
};

epcs_devinfo_t *epcs_dev_find (void)
{
	unsigned char buf[4];
	unsigned char id;
	int i;
	struct epcs_devinfo_t *dev = NULL;

	/* Read silicon id requires 3 "dummy bytes" before it's put
	 * on the wire.
	 */
	buf[0] = EPCS_READ_ID;
	buf[1] = 0;
	buf[2] = 0;
	buf[3] = 0;

	epcs_cs (1);
	epcs_snd (buf,4);
	epcs_rcv (buf,1);
	if (epcs_cs (0) == -1)
		return (NULL);
	id = buf[0];

	/* Find the info struct */
	i = 0;
	while (devinfo[i].name) {
		if (id == devinfo[i].id) {
			dev = &devinfo[i];
			break;
		}
		i++;
	}

	return (dev);
}

/***********************************************************************
 * Misc Utilities
 ***********************************************************************/
int epcs_cfgsz (void)
{
	int sz = 0;
	unsigned char buf[128];
	unsigned char *p;
	struct epcs_devinfo_t *dev = epcs_dev_find ();

	if (!dev)
		return (-1);

	/* Read in the first 128 bytes of the device */
	buf[0] = EPCS_READ_BYTES;
	buf[1] = 0;
	buf[2] = 0;
	buf[3] = 0;

	epcs_cs (1);
	epcs_snd (buf,4);
	epcs_rrcv (buf, sizeof(buf));
	epcs_cs (0);

	/* Search for the starting 0x6a which is followed by the
	 * 4-byte 'register' and 4-byte bit-count.
	 */
	p = buf;
	while (p < buf + sizeof(buf)-8) {
		if ( *p == 0x6a ) {
			/* Point to bit count and extract */
			p += 5;
			sz = *p++;
			sz |= *p++ << 8;
			sz |= *p++ << 16;
			sz |= *p++ << 24;
			/* Convert to byte count */
			sz += 7;
			sz >>= 3;
		} else if (*p == 0xff) {
			/* 0xff is ok ... just skip */
			p++;
			continue;
		} else {
			/* Not 0xff or 0x6a ... something's not
			 * right ... report 'unknown' (sz=0).
			 */
			break;
		}
	}
	return (sz);
}

int epcs_erase (unsigned start, unsigned end)
{
	unsigned off, sectsz;
	unsigned char buf[4];
	struct epcs_devinfo_t *dev = epcs_dev_find ();

	if (!dev || (start>end))
		return (-1);

	/* Erase the requested sectors. An address is required
	 * that lies within the requested sector -- we'll just
	 * use the first address in the sector.
	 */
	printf ("epcs erasing sector %d ", start);
	if (start != end)
		printf ("to %d ", end);
	sectsz = (1 << dev->sz_sect);
	while (start <= end) {
		off = start * sectsz;
		start++;

		buf[0] = EPCS_ERASE_SECT;
		buf[1] = off >> 16;
		buf[2] = off >> 8;
		buf[3] = off;

		epcs_wr_enable ();
		epcs_cs (1);
		epcs_snd (buf,4);
		epcs_cs (0);

		printf ("."); /* Some user feedback */

		/* Wait for erase to complete */
		while (epcs_status_rd() & EPCS_STATUS_WIP)
			;
	}
	printf (" done.\n");
	return (0);
}

int epcs_read (ulong addr, ulong off, ulong cnt)
{
	unsigned char buf[4];
	struct epcs_devinfo_t *dev = epcs_dev_find ();

	if (!dev)
		return (-1);

	buf[0] = EPCS_READ_BYTES;
	buf[1] = off >> 16;
	buf[2] = off >> 8;
	buf[3] = off;

	epcs_cs (1);
	epcs_snd (buf,4);
	epcs_rrcv ((unsigned char *)addr, cnt);
	epcs_cs (0);

	return (0);
}

int epcs_write (ulong addr, ulong off, ulong cnt)
{
	ulong wrcnt;
	unsigned pgsz;
	unsigned char buf[4];
	struct epcs_devinfo_t *dev = epcs_dev_find ();

	if (!dev)
		return (-1);

	pgsz = (1<<dev->sz_page);
	while (cnt) {
		if (off % pgsz)
			wrcnt = pgsz - (off % pgsz);
		else
			wrcnt = pgsz;
		wrcnt = (wrcnt > cnt) ? cnt : wrcnt;

		buf[0] = EPCS_WRITE_BYTES;
		buf[1] = off >> 16;
		buf[2] = off >> 8;
		buf[3] = off;

		epcs_wr_enable ();
		epcs_cs (1);
		epcs_snd (buf,4);
		epcs_rsnd ((unsigned char *)addr, wrcnt);
		epcs_cs (0);

		/* Wait for write to complete */
		while (epcs_status_rd() & EPCS_STATUS_WIP)
			;

		cnt -= wrcnt;
		off += wrcnt;
		addr += wrcnt;
	}

	return (0);
}

int epcs_verify (ulong addr, ulong off, ulong cnt, ulong *err)
{
	ulong rdcnt;
	unsigned char buf[256];
	unsigned char *start,*end;
	int i;

	start = end = (unsigned char *)addr;
	while (cnt) {
		rdcnt = (cnt>sizeof(buf)) ? sizeof(buf) : cnt;
		epcs_read ((ulong)buf, off, rdcnt);
		for (i=0; i<rdcnt; i++) {
			if (*end != buf[i]) {
				*err = end - start;
				return(-1);
			}
			end++;
		}
		cnt -= rdcnt;
		off += rdcnt;
	}
	return (0);
}

static int epcs_sect_erased (int sect, unsigned *offset,
		struct epcs_devinfo_t *dev)
{
	unsigned char buf[128];
	unsigned off, end;
	unsigned sectsz;
	int i;

	sectsz = (1 << dev->sz_sect);
	off = sectsz * sect;
	end = off + sectsz;

	while (off < end) {
		epcs_read ((ulong)buf, off, sizeof(buf));
		for (i=0; i < sizeof(buf); i++) {
			if (buf[i] != 0xff) {
				*offset = off + i;
				return (0);
			}
		}
		off += sizeof(buf);
	}
	return (1);
}


/***********************************************************************
 * Commands
 ***********************************************************************/
static
void do_epcs_info (struct epcs_devinfo_t *dev, int argc, char *argv[])
{
	int i;
	unsigned char stat;
	unsigned tmp;
	int erased;

	/* Basic device info */
	printf ("%s: %d kbytes (%d sectors x %d kbytes,"
		" %d bytes/page)\n",
		dev->name, 1 << (dev->size-10),
		dev->num_sects, 1 << (dev->sz_sect-10),
		1 << dev->sz_page );

	/* Status -- for now protection is all-or-nothing */
	stat = epcs_status_rd();
	printf ("status: 0x%02x (WIP:%d, WEL:%d, PROT:%s)\n",
		stat,
		(stat & EPCS_STATUS_WIP) ? 1 : 0,
	        (stat & EPCS_STATUS_WEL) ? 1 : 0,
		(stat & dev->prot_mask) ? "on" : "off" );

	/* Configuration  */
	tmp = epcs_cfgsz ();
	if (tmp) {
		printf ("config: 0x%06x (%d) bytes\n", tmp, tmp );
	} else {
		printf ("config: unknown\n" );
	}

	/* Sector info */
	for (i=0; i<dev->num_sects; i++) {
		erased = epcs_sect_erased (i, &tmp, dev);
		printf ("     %d: %06x ",
			i, i*(1<<dev->sz_sect) );
		if (erased)
			printf ("erased\n");
		else
			printf ("data @ 0x%06x\n", tmp);
	}

	return;
}

static
void do_epcs_erase (struct epcs_devinfo_t *dev, int argc, char *argv[])
{
	unsigned start,end;

	if ((argc < 3) || (argc > 4)) {
		printf ("USAGE: epcs erase sect [end]\n");
		return;
	}
	if ((epcs_status_rd() & dev->prot_mask) != 0) {
		printf ( "epcs: device protected.\n");
		return;
	}

	start = simple_strtoul (argv[2], NULL, 10);
	if (argc > 3)
		end = simple_strtoul (argv[3], NULL, 10);
	else
		end = start;
	if ((start >= dev->num_sects) || (start > end)) {
		printf ("epcs: invalid sector range: [%d:%d]\n",
			start, end );
		return;
	}

	epcs_erase (start, end);

	return;
}

static
void do_epcs_protect (struct epcs_devinfo_t *dev, int argc, char *argv[])
{
	unsigned char stat;

	/* For now protection is all-or-nothing to keep things
	 * simple. The protection bits don't map in a linear
	 * fashion ... and we would rather protect the bottom
	 * of the device since it contains the config data and
	 * leave the top unprotected for app use. But unfortunately
	 * protection works from top-to-bottom so it does
	 * really help very much from a software app point-of-view.
	 */
	if (argc < 3) {
		printf ("USAGE: epcs protect on | off\n");
		return;
	}
	if (!dev)
		return;

	/* Protection on/off is just a matter of setting/clearing
	 * all protection bits in the status register.
	 */
	stat = epcs_status_rd ();
	if (strcmp ("on", argv[2]) == 0) {
		stat |= dev->prot_mask;
	} else if (strcmp ("off", argv[2]) == 0 ) {
		stat &= ~dev->prot_mask;
	} else {
		printf ("epcs: unknown protection: %s\n", argv[2]);
		return;
	}
	epcs_status_wr (stat);
	return;
}

static
void do_epcs_read (struct epcs_devinfo_t *dev, int argc, char *argv[])
{
	ulong addr,off,cnt;
	ulong sz;

	if (argc < 5) {
		printf ("USAGE: epcs read addr offset count\n");
		return;
	}

	sz = 1 << dev->size;
	addr = simple_strtoul (argv[2], NULL, 16);
	off  = simple_strtoul (argv[3], NULL, 16);
	cnt  = simple_strtoul (argv[4], NULL, 16);
	if (off > sz) {
		printf ("offset is greater than device size"
			"... aborting.\n");
		return;
	}
	if ((off + cnt) > sz) {
		printf ("request exceeds device size"
			"... truncating.\n");
		cnt = sz - off;
	}
	printf ("epcs: read %08lx <- %06lx (0x%lx bytes)\n",
			addr, off, cnt);
	epcs_read (addr, off, cnt);

	return;
}

static
void do_epcs_write (struct epcs_devinfo_t *dev, int argc, char *argv[])
{
	ulong addr,off,cnt;
	ulong sz;
	ulong err;

	if (argc < 5) {
		printf ("USAGE: epcs write addr offset count\n");
		return;
	}
	if ((epcs_status_rd() & dev->prot_mask) != 0) {
		printf ( "epcs: device protected.\n");
		return;
	}

	sz = 1 << dev->size;
	addr = simple_strtoul (argv[2], NULL, 16);
	off  = simple_strtoul (argv[3], NULL, 16);
	cnt  = simple_strtoul (argv[4], NULL, 16);
	if (off > sz) {
		printf ("offset is greater than device size"
			"... aborting.\n");
		return;
	}
	if ((off + cnt) > sz) {
		printf ("request exceeds device size"
			"... truncating.\n");
		cnt = sz - off;
	}
	printf ("epcs: write %08lx -> %06lx (0x%lx bytes)\n",
			addr, off, cnt);
	epcs_write (addr, off, cnt);
	if (epcs_verify (addr, off, cnt, &err) != 0)
		printf ("epcs: write error at offset %06lx\n", err);

	return;
}

static
void do_epcs_verify (struct epcs_devinfo_t *dev, int argc, char *argv[])
{
	ulong addr,off,cnt;
	ulong sz;
	ulong err;

	if (argc < 5) {
		printf ("USAGE: epcs verify addr offset count\n");
		return;
	}

	sz = 1 << dev->size;
	addr = simple_strtoul (argv[2], NULL, 16);
	off  = simple_strtoul (argv[3], NULL, 16);
	cnt  = simple_strtoul (argv[4], NULL, 16);
	if (off > sz) {
		printf ("offset is greater than device size"
			"... aborting.\n");
		return;
	}
	if ((off + cnt) > sz) {
		printf ("request exceeds device size"
			"... truncating.\n");
		cnt = sz - off;
	}
	printf ("epcs: verify %08lx -> %06lx (0x%lx bytes)\n",
			addr, off, cnt);
	if (epcs_verify (addr, off, cnt, &err) != 0)
		printf ("epcs: verify error at offset %06lx\n", err);

	return;
}

/*-----------------------------------------------------------------------*/
int do_epcs (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	int len;
	struct epcs_devinfo_t *dev = epcs_dev_find ();

	if (!dev) {
		printf ("epcs: device not found.\n");
		return (-1);
	}

	if (argc < 2) {
		do_epcs_info (dev, argc, argv);
		return (0);
	}

	len = strlen (argv[1]);
	if (strncmp ("info", argv[1], len) == 0) {
		do_epcs_info (dev, argc, argv);
	} else if (strncmp ("erase", argv[1], len) == 0) {
		do_epcs_erase (dev, argc, argv);
	} else if (strncmp ("protect", argv[1], len) == 0) {
		do_epcs_protect (dev, argc, argv);
	} else if (strncmp ("read", argv[1], len) == 0) {
		do_epcs_read (dev, argc, argv);
	} else if (strncmp ("write", argv[1], len) == 0) {
		do_epcs_write (dev, argc, argv);
	} else if (strncmp ("verify", argv[1], len) == 0) {
		do_epcs_verify (dev, argc, argv);
	} else {
		printf ("epcs: unknown operation: %s\n", argv[1]);
	}

	return (0);
}

/*-----------------------------------------------------------------------*/


U_BOOT_CMD( epcs, 5, 0, do_epcs, SHORT_HELP, LONG_HELP );

#endif /* CONFIG_NIOS_EPCS */
