flash-upgrade: CFI flash identification failed

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,
i am trying to update my u-boot. Booting the generated flash-upgrade.uimg i get the following error.

Quote:

Image Name: AVR32 Flash Upgrade Utility v0.1
Image Type: AVR32 Linux Kernel Image (gzip compressed)
Data Size: 63087 Bytes = 61.6 kB
Load Address: 10000000
Entry Point: 90000000
Verifying Checksum ... OK
Uncompressing Kernel Image ... OK

Starting kernel at 90000000 (params at 11fc0040)...

AVR32 Flash upgrade utility version 0.1

HSMC configuration: 0x00030001 0x06030504 0x00080008 0x00001103
cfi: Unknown chip 0x001f:0x01d6
Panic: CFI flash identification failed

Looking in cfi.c i found

 
#define AT49BV6416	0x00d6

Will it work if i just modify the define to 0x01d6 ?

... the only thing you cannot unscramble is eggs...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

And you have a AT49BV6416 flash device on your board?

From the datasheet for AT49BV6416:

Quote:
Manufacturer Code: 001FH; Device Code: 00D6H - AT49BV6416; 00D2H - AT49BV6416T.

So no, changing the define to 0x01d6 will not make your device act as a AT49BV6416 ;) You have an AT49BV642D device, but it should be supported by the flash-upgrade utility as well, weird.

Quote:
Manufacturer Code: 001FH; Device Code: 01D6H - AT49BV642D; 01D2H - AT49BV642DT.

Hans-Christian

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Obviously not by the version on the BSP 2.0.0 CD :cry:

... the only thing you cannot unscramble is eggs...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I got exactly the same problem. Is there any way to get around this without a JTAGICEmkII.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My idea is to copy u-boot.bin to the MMC/SD and

~# flash_eraseall /dev/mtd0 
~# dd if=/media/mmcblk0p1/u-boot.bin of=/dev/mtd0 bs=1024

May this work?

... the only thing you cannot unscramble is eggs...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Not unless you modify your kernel image to allow writing to this partition (it's read-only) by default.

-S.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've solved this problem. The solution is simple but I haven't seen it documented yet. This thread definitely helped me start thinking, so thank you.

So for reasons I don't know some NGW100 boards have AT49BV6416, while others have AT49BV642D. If you try to use the flash-upgrade utility with a AT49BV642D board you get the following error...

Image Name: AVR32 Flash Upgrade Utility v0.1
Image Type: AVR32 Linux Kernel Image (gzip compressed)
Data Size: 63087 Bytes = 61.6 kB
Load Address: 10000000
Entry Point: 90000000
Verifying Checksum ... OK
Uncompressing Kernel Image ... OK

Starting kernel at 90000000 (params at 11fc0040)...

AVR32 Flash upgrade utility version 0.1

HSMC configuration: 0x00030001 0x06030504 0x00080008 0x00001103
cfi: Unknown chip 0x001f:0x01d6
Panic: CFI flash identification failed 

This is because the flash-upgrade utility only recognizes the device code 0x00D6 for the AT49BV6416. The file cfi.c must be modified to support the AT49BV642D with device code 0x01D6.

The variation of the flash chips is only relevant to the 'fixup' of the chip, which is initialization and unlocking prior to programming. They can be programmed the same way.

Heres the good news, the fixup of the AT49BV642D is automatic and so only a blank function is necessary. The AT49BV642D is unlocked on reset, unlike the AT49BV6416 (look at the datasheets).

So in cfi.c you will find...

/* Fixups go here */

static void fixup_at49bv6416(struct cfi_flash *cfi)
{
	struct erase_region tmp;
	unsigned long offset;
	unsigned int i, j;

	/*
	 * Erase regions are supposed to start at the lowest address
	 * for bottom-boot devices. The AT49BV6416 is different. Swap
	 * the erase regions to avoid confusion later.
	 */
	memcpy(&tmp, &cfi->erase_region[0], sizeof(struct erase_region));
	memcpy(&cfi->erase_region[0], &cfi->erase_region[1],
	       sizeof(struct erase_region));
	memcpy(&cfi->erase_region[1], &tmp, sizeof(struct erase_region));

	/*
	 * The chip also features a "soft unlock" operation that needs
	 * to be performed before programming. Do it now.
	 */
	offset = 0;
	for (i = 0; i < cfi->nr_erase_regions; i++) {
		for (j = 0; j < cfi->erase_region[i].nr_sectors; j++) {
			cfi_write16(cfi, ADDR_UNLOCK1, 0xaa);
			writew(0x70, cfi->fl.addr + offset);
			offset += cfi->erase_region[i].sector_size;
		}
	}
}

static const struct flash_chip atmel_chips[] = {
	{
		.name		= "AT49BV6416",
		.id		= AT49BV6416,
		.fixup		= fixup_at49bv6416,
	},
};

Change this to...

/* Fixups go here */

static void fixup_at49bv6416(struct cfi_flash *cfi)
{
	struct erase_region tmp;
	unsigned long offset;
	unsigned int i, j;

	/*
	 * Erase regions are supposed to start at the lowest address
	 * for bottom-boot devices. The AT49BV6416 is different. Swap
	 * the erase regions to avoid confusion later.
	 */
	memcpy(&tmp, &cfi->erase_region[0], sizeof(struct erase_region));
	memcpy(&cfi->erase_region[0], &cfi->erase_region[1],
	       sizeof(struct erase_region));
	memcpy(&cfi->erase_region[1], &tmp, sizeof(struct erase_region));

	/*
	 * The chip also features a "soft unlock" operation that needs
	 * to be performed before programming. Do it now.
	 */
	offset = 0;
	for (i = 0; i < cfi->nr_erase_regions; i++) {
		for (j = 0; j < cfi->erase_region[i].nr_sectors; j++) {
			cfi_write16(cfi, ADDR_UNLOCK1, 0xaa);
			writew(0x70, cfi->fl.addr + offset);
			offset += cfi->erase_region[i].sector_size;
		}
	}
}

static void fixup_at49bv642d(struct cfi_flash *cfi)
{
	/*
	 * Do nothing...
	 */
}

static const struct flash_chip atmel_chips[] = {
	{
		.name		= "AT49BV6416",
		.id		= AT49BV6416,
		.fixup		= fixup_at49bv6416,
	},
	{
		.name		= "AT49BV642D",
		.id		= AT49BV642D,
		.fixup		= fixup_at49bv642d,
	}
};

And change...

/* Chip identification stuff */
#define MFR_ATMEL	0x001f

#define AT49BV6416	0x00d6

To...

/* Chip identification stuff */
#define MFR_ATMEL	0x001f

#define AT49BV6416	0x00d6
#define AT49BV642D	0x01d6

With the appropriate toolchain and newly compiled u-boot.bin in place, type 'make' and you should get a flash-upgrade.uimg without any errors.

I have done this to upgrade my u-boot 1.1.4 to 1.3.0 successfully.

I hope this helps people stuck with the AT49BV642D, since using the flash-upgrade utility is definitely the easiest and fastest way of upgrading u-boot. I spent alot of headache looking at alternatives before I finally went back to this... I had thought modifying flash-upgrade would have been difficult, but fortunately it wasn't.