/*
 * MOUSSE/MPC8240 Board definitions.
 * Flash Routines for MOUSSE onboard AMD29LV106DB devices
 *
 * (C) Copyright 2000
 * Marius Groeger <mgroeger@sysgo.de>
 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 *
 * (C) Copyright 2000
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * (C) Copyright 1999, by Curt McDowell, 08-06-99, Broadcom Corp.
 * (C) Copyright 2001, James Dougherty, 07/18/01, Broadcom Corp.
 *
 * 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>
#include <mpc8xx.h>
#include <malloc.h>
#include "mousse.h"
#include "flash.h"

int flashLibDebug = 0;
int flashLibInited = 0;

#define OK  0
#define ERROR -1
#define STATUS int
#define PRINTF			if (flashLibDebug) printf
#if 0
#define PRIVATE			static
#else
#define PRIVATE
#endif

flash_info_t flash_info[CFG_MAX_FLASH_BANKS];

#define SLEEP_DELAY    166
#define FLASH_SECTOR_SIZE   (64*1024)
/***********************************************************************
 *
 * Virtual Flash Devices on Mousse board
 *
 * These must be kept in sync with the definitions in flashLib.h.
 *
 ***********************************************************************/

PRIVATE flash_dev_t flashDev[] = {
    /* Bank 0 sector SA0 (16 kB) */
    {	"SA0",FLASH0_BANK, FLASH0_SEG0_START, 1, 14,
	FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
    },
    /* Bank 0 sector SA1 (8 kB) */
    {	"SA1", FLASH0_BANK, FLASH0_SEG0_START + 0x4000, 1, 13,
	FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
    },
    /* Bank 0 sector SA2 (8 kB) */
    {	"SA2", FLASH0_BANK, FLASH0_SEG0_START + 0x6000, 1, 13,
	FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
    },
    /* Bank 0 sector SA3 is occluded by Mousse I/O devices */
    /* Bank 0 sectors SA4-SA18, after Mousse devices up to PLCC (960 kB)  */
    {	"KERNEL", FLASH0_BANK, FLASH0_SEG1_START, 15, 16,
	FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
    },
    /* Bank 0 sectors SA19-SA26, jumper can occlude this by PLCC (512 kB) */
    /* This is where the Kahlua boot vector and boot ROM code resides. */
    {	"BOOT",FLASH0_BANK, FLASH0_SEG2_START, 8, 16,
	FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
    },
    /* Bank 0 sectors SA27-SA34 (512 kB) */
    {	"RAMDISK",FLASH0_BANK, FLASH0_SEG3_START, 8, 16,
	FLASH0_VENDOR_ID, FLASH0_DEVICE_ID
    },
};

int flashDevCount = (sizeof (flashDev) / sizeof (flashDev[0]));

#define DEV(no)			(&flashDev[no])
#define DEV_NO(dev)		((dev) - flashDev)

/***********************************************************************
 *
 * Private Flash Routines
 *
 ***********************************************************************/

/*
 * The convention is:
 *
 * "addr" is always the PROM raw address, which is the address of an
 * 8-bit quantity for flash 0 and 16-bit quantity for flash 1.
 *
 * "pos" is always a logical byte position from the PROM beginning.
 */

#define FLASH0_ADDR(dev, addr) \
	((unsigned char *) ((dev)->base + (addr)))

#define FLASH0_WRITE(dev, addr, value) \
	(*FLASH0_ADDR(dev, addr) = (value))

#define FLASH0_READ(dev, addr) \
	(*FLASH0_ADDR(dev, addr))

PRIVATE int flashCheck (flash_dev_t * dev)
{
	if (!flashLibInited) {
		printf ("flashCheck: flashLib not initialized\n");
		return ERROR;
	}

	if (dev < &flashDev[0] || dev >= &flashDev[flashDevCount]) {
		printf ("flashCheck: Bad dev parameter\n");
		return ERROR;
	}

	if (!dev->found) {
		printf ("flashCheck: Device %d not available\n", DEV_NO (dev));
		return ERROR;
	}

	return OK;
}

PRIVATE void flashReset (flash_dev_t * dev)
{
	PRINTF ("flashReset: dev=%d\n", DEV_NO (dev));

	if (dev->bank == FLASH0_BANK) {
		FLASH0_WRITE (dev, 0x555, 0xaa);
		FLASH0_WRITE (dev, 0xaaa, 0x55);
		FLASH0_WRITE (dev, 0x555, 0xf0);
	}

	udelay (SLEEP_DELAY);

	PRINTF ("flashReset: done\n");
}

PRIVATE int flashProbe (flash_dev_t * dev)
{
	int rv, deviceID, vendorID;

	PRINTF ("flashProbe: dev=%d\n", DEV_NO (dev));

	if (dev->bank != FLASH0_BANK) {
		rv = ERROR;
		goto DONE;
	}

	FLASH0_WRITE (dev, 0xaaa, 0xaa);
	FLASH0_WRITE (dev, 0x555, 0x55);
	FLASH0_WRITE (dev, 0xaaa, 0x90);

	udelay (SLEEP_DELAY);

	vendorID = FLASH0_READ (dev, 0);
	deviceID = FLASH0_READ (dev, 2);

	FLASH0_WRITE (dev, 0, 0xf0);

	PRINTF ("flashProbe: vendor=0x%x device=0x%x\n", vendorID, deviceID);

	if (vendorID == dev->vendorID && deviceID == dev->deviceID)
		rv = OK;
	else
		rv = ERROR;

  DONE:
	PRINTF ("flashProbe: rv=%d\n", rv);

	return rv;
}

PRIVATE int flashWait (flash_dev_t * dev, int addr, int expect, int erase)
{
	int rv = ERROR;
	int i, data;
	int polls;

#if 0
	PRINTF ("flashWait: dev=%d addr=0x%x expect=0x%x erase=%d\n",
		DEV_NO (dev), addr, expect, erase);
#endif

	if (dev->bank != FLASH0_BANK) {
		rv = ERROR;
		goto done;
	}

	if (erase)
		polls = FLASH_ERASE_SECTOR_TIMEOUT;	/* Ticks */
	else
		polls = FLASH_PROGRAM_POLLS;	/* Loops */

	for (i = 0; i < polls; i++) {
		if (erase)
			udelay (SLEEP_DELAY);

		data = FLASH0_READ (dev, addr);

		if (((data ^ expect) & 0x80) == 0) {
			rv = OK;
			goto done;
		}

		if (data & 0x20) {
			/*
			 * If the 0x20 bit has come on, it could actually be because
			 * the operation succeeded, so check the done bit again.
			 */

			data = FLASH0_READ (dev, addr);

			if (((data ^ expect) & 0x80) == 0) {
				rv = OK;
				goto done;
			}

			printf ("flashWait: Program error (dev: %d, addr: 0x%x)\n",
					DEV_NO (dev), addr);

			flashReset (dev);
			rv = ERROR;
			goto done;
		}
	}

	printf ("flashWait: Timeout %s (dev: %d, addr: 0x%x)\n",
		erase ? "erasing sector" : "programming byte",
		DEV_NO (dev), addr);

  done:

#if 0
	PRINTF ("flashWait: rv=%d\n", rv);
#endif

	return rv;
}

/***********************************************************************
 *
 * Public Flash Routines
 *
 ***********************************************************************/

STATUS flashLibInit (void)
{
	int i;

	PRINTF ("flashLibInit: devices=%d\n", flashDevCount);

	for (i = 0; i < flashDevCount; i++) {
		flash_dev_t *dev = &flashDev[i];

		/*
		 * For bank 1, probe both without and with byte swappage,
		 * so that this module works on both old and new Mousse boards.
		 */

		flashReset (dev);

		if (flashProbe (dev) != ERROR)
			dev->found = 1;

		flashReset (dev);

		if (flashProbe (dev) != ERROR)
			dev->found = 1;

		dev->swap = 0;

		if (dev->found) {
			PRINTF ("\n  FLASH %s[%d]: iobase=0x%x - %d sectors %d KB",
				flashDev[i].name, i, flashDev[i].base,
				flashDev[i].sectors,
				(flashDev[i].sectors * FLASH_SECTOR_SIZE) / 1024);

		}
	}

	flashLibInited = 1;

	PRINTF ("flashLibInit: done\n");

	return OK;
}

STATUS flashEraseSector (flash_dev_t * dev, int sector)
{
	int pos, addr;

	PRINTF ("flashErasesector: dev=%d sector=%d\n", DEV_NO (dev), sector);

	if (flashCheck (dev) == ERROR)
		return ERROR;

	if (sector < 0 || sector >= dev->sectors) {
		printf ("flashEraseSector: Sector out of range (dev: %d, sector: %d)\n", DEV_NO (dev), sector);
		return ERROR;
	}

	pos = FLASH_SECTOR_POS (dev, sector);

	if (dev->bank != FLASH0_BANK) {
		return ERROR;
	}

	addr = pos;

	FLASH0_WRITE (dev, 0xaaa, 0xaa);
	FLASH0_WRITE (dev, 0x555, 0x55);
	FLASH0_WRITE (dev, 0xaaa, 0x80);
	FLASH0_WRITE (dev, 0xaaa, 0xaa);
	FLASH0_WRITE (dev, 0x555, 0x55);
	FLASH0_WRITE (dev, addr, 0x30);

	return flashWait (dev, addr, 0xff, 1);
}

/*
 * Note: it takes about as long to flash all sectors together with Chip
 * Erase as it does to flash them one at a time (about 30 seconds for 2
 * MB).  Also since we want to be able to treat subsets of sectors as if
 * they were complete devices, we don't use Chip Erase.
 */

STATUS flashErase (flash_dev_t * dev)
{
	int sector;

	PRINTF ("flashErase: dev=%d sectors=%d\n", DEV_NO (dev), dev->sectors);

	if (flashCheck (dev) == ERROR)
		return ERROR;

	for (sector = 0; sector < dev->sectors; sector++) {
		if (flashEraseSector (dev, sector) == ERROR)
			return ERROR;
	}
	return OK;
}

/*
 * Read and write bytes
 */

STATUS flashRead (flash_dev_t * dev, int pos, char *buf, int len)
{
	int addr, words;

	PRINTF ("flashRead: dev=%d pos=0x%x buf=0x%x len=0x%x\n",
		DEV_NO (dev), pos, (int) buf, len);

	if (flashCheck (dev) == ERROR)
		return ERROR;

	if (pos < 0 || len < 0 || pos + len > FLASH_MAX_POS (dev)) {
		printf ("flashRead: Position out of range "
			"(dev: %d, pos: 0x%x, len: 0x%x)\n",
			DEV_NO (dev), pos, len);
		return ERROR;
	}

	if (len == 0)
		return OK;

	if (dev->bank == FLASH0_BANK) {
		addr = pos;
		words = len;

		PRINTF ("flashRead: memcpy(0x%x, 0x%x, 0x%x)\n",
			(int) buf, (int) FLASH0_ADDR (dev, pos), len);

		memcpy (buf, FLASH0_ADDR (dev, addr), words);

	}
	PRINTF ("flashRead: rv=OK\n");

	return OK;
}

STATUS flashWrite (flash_dev_t * dev, int pos, char *buf, int len)
{
	int addr, words;

	PRINTF ("flashWrite: dev=%d pos=0x%x buf=0x%x len=0x%x\n",
		DEV_NO (dev), pos, (int) buf, len);

	if (flashCheck (dev) == ERROR)
		return ERROR;

	if (pos < 0 || len < 0 || pos + len > FLASH_MAX_POS (dev)) {
		printf ("flashWrite: Position out of range "
			"(dev: %d, pos: 0x%x, len: 0x%x)\n",
			DEV_NO (dev), pos, len);
		return ERROR;
	}

	if (len == 0)
		return OK;

	if (dev->bank == FLASH0_BANK) {
		unsigned char tmp;

		addr = pos;
		words = len;

		while (words--) {
			tmp = *buf;
			if (~FLASH0_READ (dev, addr) & tmp) {
				printf ("flashWrite: Attempt to program 0 to 1 "
					"(dev: %d, addr: 0x%x, data: 0x%x)\n",
					DEV_NO (dev), addr, tmp);
				return ERROR;
			}
			FLASH0_WRITE (dev, 0xaaa, 0xaa);
			FLASH0_WRITE (dev, 0x555, 0x55);
			FLASH0_WRITE (dev, 0xaaa, 0xa0);
			FLASH0_WRITE (dev, addr, tmp);
			if (flashWait (dev, addr, tmp, 0) < 0)
				return ERROR;
			buf++;
			addr++;
		}
	}

	PRINTF ("flashWrite: rv=OK\n");

	return OK;
}

/*
 * flashWritable returns TRUE if a range contains all F's.
 */

STATUS flashWritable (flash_dev_t * dev, int pos, int len)
{
	int addr, words;
	int rv = ERROR;

	PRINTF ("flashWritable: dev=%d pos=0x%x len=0x%x\n",
			DEV_NO (dev), pos, len);

	if (flashCheck (dev) == ERROR)
		goto done;

	if (pos < 0 || len < 0 || pos + len > FLASH_MAX_POS (dev)) {
		printf ("flashWritable: Position out of range "
			"(dev: %d, pos: 0x%x, len: 0x%x)\n",
			DEV_NO (dev), pos, len);
		goto done;
	}

	if (len == 0) {
		rv = 1;
		goto done;
	}

	if (dev->bank == FLASH0_BANK) {
		addr = pos;
		words = len;

		while (words--) {
			if (FLASH0_READ (dev, addr) != 0xff) {
				rv = 0;
				goto done;
			}
			addr++;
		}
	}

	rv = 1;

  done:
	PRINTF ("flashWrite: rv=%d\n", rv);
	return rv;
}


/*
 * NOTE: the below code cannot run from FLASH!!!
 */
/***********************************************************************
 *
 * Flash Diagnostics
 *
 ***********************************************************************/

STATUS flashDiag (flash_dev_t * dev)
{
	unsigned int *buf = 0;
	int i, len, sector;
	int rv = ERROR;

	if (flashCheck (dev) == ERROR)
		return ERROR;

	printf ("flashDiag: Testing device %d, "
		"base: 0x%x, %d sectors @ %d kB = %d kB\n",
		DEV_NO (dev), dev->base,
		dev->sectors,
		1 << (dev->lgSectorSize - 10),
		dev->sectors << (dev->lgSectorSize - 10));

	len = 1 << dev->lgSectorSize;

	printf ("flashDiag: Erasing\n");

	if (flashErase (dev) == ERROR) {
		printf ("flashDiag: Erase failed\n");
		goto done;
	}
	printf ("%d bytes requested ...\n", len);
	buf = malloc (len);
	printf ("allocated %d bytes ...\n", len);
	if (buf == 0) {
		printf ("flashDiag: Out of memory\n");
		goto done;
	}

	/*
	 * Write unique counting pattern to each sector
	 */

	for (sector = 0; sector < dev->sectors; sector++) {
		printf ("flashDiag: Write sector %d\n", sector);

		for (i = 0; i < len / 4; i++)
			buf[i] = sector << 24 | i;

		if (flashWrite (dev,
				sector << dev->lgSectorSize,
				(char *) buf, len) == ERROR) {
			printf ("flashDiag: Write failed (dev: %d, sector: %d)\n",
				DEV_NO (dev), sector);
			goto done;
		}
	}

	/*
	 * Verify
	 */

	for (sector = 0; sector < dev->sectors; sector++) {
		printf ("flashDiag: Verify sector %d\n", sector);

		if (flashRead (dev,
				   sector << dev->lgSectorSize,
				   (char *) buf, len) == ERROR) {
			printf ("flashDiag: Read failed (dev: %d, sector: %d)\n",
				DEV_NO (dev), sector);
			goto done;
		}

		for (i = 0; i < len / 4; i++) {
			if (buf[i] != (sector << 24 | i)) {
				printf ("flashDiag: Verify error "
					"(dev: %d, sector: %d, offset: 0x%x)\n",
					DEV_NO (dev), sector, i);
				printf ("flashDiag: Expected 0x%08x, got 0x%08x\n",
					sector << 24 | i, buf[i]);

				goto done;
			}
		}
	}

	printf ("flashDiag: Erasing\n");

	if (flashErase (dev) == ERROR) {
		printf ("flashDiag: Final erase failed\n");
		goto done;
	}

	rv = OK;

  done:
	if (buf)
		free (buf);

	if (rv == OK)
		printf ("flashDiag: Device %d passed\n", DEV_NO (dev));
	else
		printf ("flashDiag: Device %d failed\n", DEV_NO (dev));

	return rv;
}

STATUS flashDiagAll (void)
{
	int i;
	int rv = OK;

	PRINTF ("flashDiagAll: devices=%d\n", flashDevCount);

	for (i = 0; i < flashDevCount; i++) {
		flash_dev_t *dev = &flashDev[i];

		if (dev->found && flashDiag (dev) == ERROR)
			rv = ERROR;
	}

	if (rv == OK)
		printf ("flashDiagAll: Passed\n");
	else
		printf ("flashDiagAll: Failed because of earlier errors\n");

	return OK;
}


/*-----------------------------------------------------------------------
 */
unsigned long flash_init (void)
{
	unsigned long size = 0;
	flash_dev_t *dev = NULL;

	flashLibInit ();

	/*
	 * Provide info for FLASH (up to 960K) of Kernel Image data.
	 */
	dev = FLASH_DEV_BANK0_LOW;
	flash_info[FLASH_BANK_KERNEL].flash_id =
			(dev->vendorID << 16) | dev->deviceID;
	flash_info[FLASH_BANK_KERNEL].sector_count = dev->sectors;
	flash_info[FLASH_BANK_KERNEL].size =
			flash_info[FLASH_BANK_KERNEL].sector_count * FLASH_SECTOR_SIZE;
	flash_info[FLASH_BANK_KERNEL].start[FIRST_SECTOR] = dev->base;
	size += flash_info[FLASH_BANK_KERNEL].size;

	/*
	 * Provide info for 512K PLCC FLASH ROM (U-Boot)
	 */
	dev = FLASH_DEV_BANK0_BOOT;
	flash_info[FLASH_BANK_BOOT].flash_id =
			(dev->vendorID << 16) | dev->deviceID;
	flash_info[FLASH_BANK_BOOT].sector_count = dev->sectors;
	flash_info[FLASH_BANK_BOOT].size =
			flash_info[FLASH_BANK_BOOT].sector_count * FLASH_SECTOR_SIZE;
	flash_info[FLASH_BANK_BOOT].start[FIRST_SECTOR] = dev->base;
	size += flash_info[FLASH_BANK_BOOT].size;


	/*
	 * Provide info for 512K FLASH0 segment (U-Boot)
	 */
	dev = FLASH_DEV_BANK0_HIGH;
	flash_info[FLASH_BANK_AUX].flash_id =
			(dev->vendorID << 16) | dev->deviceID;
	flash_info[FLASH_BANK_AUX].sector_count = dev->sectors;
	flash_info[FLASH_BANK_AUX].size =
			flash_info[FLASH_BANK_AUX].sector_count * FLASH_SECTOR_SIZE;
	flash_info[FLASH_BANK_AUX].start[FIRST_SECTOR] = dev->base;
	size += flash_info[FLASH_BANK_AUX].size;


	return size;
}

/*
 * Get flash device from U-Boot flash info.
 */
flash_dev_t *getFlashDevFromInfo (flash_info_t * info)
{
	int i;

	if (!info)
		return NULL;

	for (i = 0; i < flashDevCount; i++) {
		flash_dev_t *dev = &flashDev[i];

		if (dev->found && (dev->base == info->start[0]))
			return dev;
	}
	printf ("ERROR: notice, no FLASH mapped at address 0x%x\n",
			(unsigned int) info->start[0]);
	return NULL;
}

ulong flash_get_size (vu_long * addr, flash_info_t * info)
{
	int i;

	for (i = 0; i < flashDevCount; i++) {
		flash_dev_t *dev = &flashDev[i];

		if (dev->found) {
			if (dev->base == (unsigned int) addr) {
				info->flash_id = (dev->vendorID << 16) | dev->deviceID;
				info->sector_count = dev->sectors;
				info->size = info->sector_count * FLASH_SECTOR_SIZE;
				return dev->sectors * FLASH_SECTOR_SIZE;
			}
		}
	}
	return 0;
}

void flash_print_info (flash_info_t * info)
{
	int i;
	unsigned int chip;

	if (info->flash_id == FLASH_UNKNOWN) {
		printf ("missing or unknown FLASH type\n");
		return;
	}

	switch ((info->flash_id >> 16) & 0xff) {
	case 0x1:
		printf ("AMD ");
		break;
	default:
		printf ("Unknown Vendor ");
		break;
	}
	chip = (unsigned int) info->flash_id & 0x000000ff;

	switch (chip) {

	case AMD_ID_F040B:
		printf ("AM29F040B (4 Mbit)\n");
		break;

	case AMD_ID_LV160B:
	case FLASH_AM160LV:
	case 0x49:
		printf ("AM29LV160B (16 Mbit / 2M x 8bit)\n");
		break;

	default:
		printf ("Unknown Chip Type:0x%x\n", chip);
		break;
	}

	printf ("  Size: %ld bytes in %d Sectors\n",
		info->size, info->sector_count);

	printf ("  Sector Start Addresses:");
	for (i = 0; i < info->sector_count; ++i) {
		if ((i % 5) == 0)
			printf ("\n   ");
		printf (" %08lX%s",
			info->start[FIRST_SECTOR] + i * FLASH_SECTOR_SIZE,
			info->protect[i] ? " (RO)" : "     ");
	}
	printf ("\n");
}


/*
 * Erase a range of flash sectors.
 */
int flash_erase (flash_info_t * info, int s_first, int s_last)
{
	vu_long *addr = (vu_long *) (info->start[0]);
	int prot, sect, l_sect;
	flash_dev_t *dev = NULL;

	if ((s_first < 0) || (s_first > s_last)) {
		if (info->flash_id == FLASH_UNKNOWN) {
			printf ("- missing\n");
		} else {
			printf ("- no sectors to erase\n");
		}
		return 1;
	}

	prot = 0;
	for (sect = s_first; sect <= s_last; sect++) {
		if (info->protect[sect]) {
			prot++;
		}
	}

	if (prot) {
		printf ("- Warning: %d protected sectors will not be erased!\n",
			prot);
	} else {
		printf ("\n");
	}

	l_sect = -1;

	/* Start erase on unprotected sectors */
	dev = getFlashDevFromInfo (info);
	if (dev) {
		printf ("Erase FLASH[%s] -%d sectors:", dev->name, dev->sectors);
		for (sect = s_first; sect <= s_last; sect++) {
			if (info->protect[sect] == 0) {	/* not protected */
				addr = (vu_long *) (dev->base);
				/*   printf("erase_sector: sector=%d, addr=0x%x\n",
				   sect, addr); */
				printf (".");
				if (ERROR == flashEraseSector (dev, sect)) {
					printf ("ERROR: could not erase sector %d on FLASH[%s]\n", sect, dev->name);
					return 1;
				}
			}
		}
	}
	printf (" done\n");
	return 0;
}

/*-----------------------------------------------------------------------
 * Write a word to Flash, returns:
 * 0 - OK
 * 1 - write timeout
 * 2 - Flash not erased
 */
static int write_word (flash_info_t * info, ulong dest, ulong data)
{

	flash_dev_t *dev = getFlashDevFromInfo (info);
	int addr = dest - info->start[0];

	if (!dev)
		return 1;

	if (OK != flashWrite (dev, addr, (char *) &data, sizeof (ulong))) {
		printf ("ERROR: could not write to addr=0x%x, data=0x%x\n",
			(unsigned int) addr, (unsigned) data);
		return 1;
	}

	if ((addr % FLASH_SECTOR_SIZE) == 0)
		printf (".");


	PRINTF ("write_word:0x%x, base=0x%x, addr=0x%x, data=0x%x\n",
		(unsigned) info->start[0],
		(unsigned) dest,
		(unsigned) (dest - info->start[0]), (unsigned) data);

	return (0);
}


/*-----------------------------------------------------------------------
 * Copy memory to flash, returns:
 * 0 - OK
 * 1 - write timeout
 * 2 - Flash not erased
 */

int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
{
	ulong cp, wp, data;
	int i, l, rc;
	flash_dev_t *dev = getFlashDevFromInfo (info);

	if (dev) {
		printf ("FLASH[%s]:", dev->name);
		wp = (addr & ~3);	/* get lower word aligned address */

		/*
		 * handle unaligned start bytes
		 */
		if ((l = addr - wp) != 0) {
			data = 0;
			for (i = 0, cp = wp; i < l; ++i, ++cp) {
				data = (data << 8) | (*(uchar *) cp);
			}
			for (; i < 4 && cnt > 0; ++i) {
				data = (data << 8) | *src++;
				--cnt;
				++cp;
			}
			for (; cnt == 0 && i < 4; ++i, ++cp) {
				data = (data << 8) | (*(uchar *) cp);
			}
			if ((rc = write_word (info, wp, data)) != 0) {
				return (rc);
			}
			wp += 4;
		}

		/*
		 * handle word aligned part
		 */
		while (cnt >= 4) {
			data = 0;
			for (i = 0; i < 4; ++i) {
				data = (data << 8) | *src++;
			}
			if ((rc = write_word (info, wp, data)) != 0) {
				return (rc);
			}
			wp += 4;
			cnt -= 4;
		}

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

		/*
		 * handle unaligned tail bytes
		 */
		data = 0;
		for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
			data = (data << 8) | *src++;
			--cnt;
		}
		for (; i < 4; ++i, ++cp) {
			data = (data << 8) | (*(uchar *) cp);
		}

		return (write_word (info, wp, data));
	}
	return 1;
}

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