/*
 * (C) Copyright 2003, 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(CONFIG_NIOS_ASMI)
#include <command.h>
#include <nios-io.h>

#if !defined(CFG_NIOS_ASMIBASE)
#error "*** CFG_NIOS_ASMIBASE not defined ***"
#endif

/*-----------------------------------------------------------------------*/
#define SHORT_HELP\
	"asmi    - read/write Cyclone ASMI configuration device.\n"

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


/*-----------------------------------------------------------------------*/
/* Operation codes for serial configuration devices
 */
#define ASMI_WRITE_ENA		0x06	/* Write enable */
#define ASMI_WRITE_DIS		0x04	/* Write disable */
#define ASMI_READ_STAT		0x05	/* Read status */
#define ASMI_READ_BYTES		0x03	/* Read bytes */
#define ASMI_READ_ID		0xab	/* Read silicon id */
#define ASMI_WRITE_STAT		0x01	/* Write status */
#define ASMI_WRITE_BYTES	0x02	/* Write bytes */
#define ASMI_ERASE_BULK		0xc7	/* Erase entire device */
#define ASMI_ERASE_SECT		0xd8	/* Erase sector */

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

static nios_asmi_t *asmi = (nios_asmi_t *)CFG_NIOS_ASMIBASE;

/***********************************************************************
 * Device access
 ***********************************************************************/
static void asmi_cs (int assert)
{
	if (assert) {
		asmi->control |= NIOS_ASMI_SSO;
	} else {
		/* Let all bits shift out */
		while ((asmi->status & NIOS_ASMI_TMT) == 0)
			;
		asmi->control &= ~NIOS_ASMI_SSO;
	}
}

static void asmi_tx (unsigned char c)
{
	while ((asmi->status & NIOS_ASMI_TRDY) == 0)
		;
	asmi->txdata = c;
}

static int asmi_rx (void)
{
	while ((asmi->status & NIOS_ASMI_RRDY) == 0)
		;
	return (asmi->rxdata);
}

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

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

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

static void asmi_rcv (unsigned char *dst, int len)
{
	while (len--) {
		asmi_tx (0);
		*dst++ = asmi_rx ();
	}
}

static void asmi_rrcv (unsigned char *dst, int len)
{
	while (len--) {
		asmi_tx (0);
		*dst++ = asmi_bitrev (asmi_rx ());
	}
}

static void asmi_snd (unsigned char *src, int len)
{
	while (len--) {
		asmi_tx (*src++);
		asmi_rx ();
	}
}

static void asmi_rsnd (unsigned char *src, int len)
{
	while (len--) {
		asmi_tx (asmi_bitrev (*src++));
		asmi_rx ();
	}
}

static void asmi_wr_enable (void)
{
	asmi_cs (1);
	asmi_tx (ASMI_WRITE_ENA);
	asmi_rx ();
	asmi_cs (0);
}

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

	asmi_cs (1);
	asmi_tx (ASMI_READ_STAT);
	asmi_rx ();
	asmi_tx (0);
	status = asmi_rx ();
	asmi_cs (0);
	return (status);
}

static void asmi_status_wr (unsigned char status)
{
	asmi_wr_enable ();
	asmi_cs (1);
	asmi_tx (ASMI_WRITE_STAT);
	asmi_rx ();
	asmi_tx (status);
	asmi_rx ();
	asmi_cs (0);
	return;
}

/***********************************************************************
 * Device information
 ***********************************************************************/
typedef struct asmi_devinfo_t {
	const char 	*name;		/* Device name */
	unsigned char	id;		/* Device silicon id */
	unsigned char	size;		/* Total size log2(bytes)*/
	unsigned char	num_sects;	/* Number of sectors */
	unsigned char	sz_sect;	/* Sector size log2(bytes) */
	unsigned char	sz_page;	/* Page size log2(bytes) */
	unsigned char   prot_mask;	/* Protection mask */
}asmi_devinfo_t;

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

static asmi_devinfo_t *asmi_dev_find (void)
{
	unsigned char buf[4];
	unsigned char id;
	int i;
	struct asmi_devinfo_t *dev = NULL;

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

	asmi_cs (1);
	asmi_snd (buf,4);
	asmi_rcv (buf,1);
	asmi_cs (0);
	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
 ***********************************************************************/
static unsigned asmi_cfgsz (void)
{
	unsigned sz = 0;
	unsigned char buf[128];
	unsigned char *p;

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

	asmi_cs (1);
	asmi_snd (buf,4);
	asmi_rrcv (buf, sizeof(buf));
	asmi_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);
}

static int asmi_erase (unsigned start, unsigned end)
{
	unsigned off, sectsz;
	unsigned char buf[4];
	struct asmi_devinfo_t *dev = asmi_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 ("asmi 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] = ASMI_ERASE_SECT;
		buf[1] = off >> 16;
		buf[2] = off >> 8;
		buf[3] = off;

		asmi_wr_enable ();
		asmi_cs (1);
		asmi_snd (buf,4);
		asmi_cs (0);

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

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

static int asmi_read (ulong addr, ulong off, ulong cnt)
{
	unsigned char buf[4];

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

	asmi_cs (1);
	asmi_snd (buf,4);
	asmi_rrcv ((unsigned char *)addr, cnt);
	asmi_cs (0);

	return (0);
}

static
int asmi_write (ulong addr, ulong off, ulong cnt)
{
	ulong wrcnt;
	unsigned pgsz;
	unsigned char buf[4];
	struct asmi_devinfo_t *dev = asmi_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] = ASMI_WRITE_BYTES;
		buf[1] = off >> 16;
		buf[2] = off >> 8;
		buf[3] = off;

		asmi_wr_enable ();
		asmi_cs (1);
		asmi_snd (buf,4);
		asmi_rsnd ((unsigned char *)addr, wrcnt);
		asmi_cs (0);

		/* Wait for write to complete */
		while (asmi_status_rd() & ASMI_STATUS_WIP)
			;

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

	return (0);
}

static
int asmi_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;
		asmi_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 asmi_sect_erased (int sect, unsigned *offset,
		struct asmi_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) {
		asmi_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_asmi_info (struct asmi_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 = asmi_status_rd();
	printf ("status: 0x%02x (WIP:%d, WEL:%d, PROT:%s)\n",
		stat,
		(stat & ASMI_STATUS_WIP) ? 1 : 0,
	        (stat & ASMI_STATUS_WEL) ? 1 : 0,
		(stat & dev->prot_mask) ? "on" : "off" );

	/* Configuration  */
	tmp = asmi_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 = asmi_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_asmi_erase (struct asmi_devinfo_t *dev, int argc, char *argv[])
{
	unsigned start,end;

	if ((argc < 3) || (argc > 4)) {
		printf ("USAGE: asmi erase sect [end]\n");
		return;
	}
	if ((asmi_status_rd() & dev->prot_mask) != 0) {
		printf ( "asmi: 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 ("asmi: invalid sector range: [%d:%d]\n",
			start, end );
		return;
	}

	asmi_erase (start, end);

	return;
}

static
void do_asmi_protect (struct asmi_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: asmi 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 = asmi_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 ("asmi: unknown protection: %s\n", argv[2]);
		return;
	}
	asmi_status_wr (stat);
	return;
}

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

	if (argc < 5) {
		printf ("USAGE: asmi 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 ("asmi: read %08lx <- %06lx (0x%lx bytes)\n",
			addr, off, cnt);
	asmi_read (addr, off, cnt);

	return;
}

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

	if (argc < 5) {
		printf ("USAGE: asmi write addr offset count\n");
		return;
	}
	if ((asmi_status_rd() & dev->prot_mask) != 0) {
		printf ( "asmi: 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 ("asmi: write %08lx -> %06lx (0x%lx bytes)\n",
			addr, off, cnt);
	asmi_write (addr, off, cnt);
	if (asmi_verify (addr, off, cnt, &err) != 0)
		printf ("asmi: write error at offset %06lx\n", err);

	return;
}

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

	if (argc < 5) {
		printf ("USAGE: asmi 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 ("asmi: verify %08lx -> %06lx (0x%lx bytes)\n",
			addr, off, cnt);
	if (asmi_verify (addr, off, cnt, &err) != 0)
		printf ("asmi: verify error at offset %06lx\n", err);

	return;
}

/*-----------------------------------------------------------------------*/
int do_asmi (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	int len;
	struct asmi_devinfo_t *dev = asmi_dev_find ();

	if (argc < 2) {
		printf ("Usage:%s", LONG_HELP);
		return (0);
	}

	if (!dev) {
		printf ("asmi: device not found.\n");
		return (0);
	}

	len = strlen (argv[1]);
	if (strncmp ("info", argv[1], len) == 0) {
		do_asmi_info ( dev, argc, argv);
	} else if (strncmp ("erase", argv[1], len) == 0) {
		do_asmi_erase (dev, argc, argv);
	} else if (strncmp ("protect", argv[1], len) == 0) {
		do_asmi_protect (dev, argc, argv);
	} else if (strncmp ("read", argv[1], len) == 0) {
		do_asmi_read (dev, argc, argv);
	} else if (strncmp ("write", argv[1], len) == 0) {
		do_asmi_write (dev, argc, argv);
	} else if (strncmp ("verify", argv[1], len) == 0) {
		do_asmi_verify (dev, argc, argv);
	} else {
		printf ("asmi: unknown operation: %s\n", argv[1]);
	}

	return (0);
}

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


U_BOOT_CMD( asmi, 5, 0, do_asmi, SHORT_HELP, LONG_HELP );

#endif /* CONFIG_NIOS_ASMI */
