/*
 * 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;
}

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