[U-Boot-Users] make uboot working with at49bv322d atmel flash

Lucas Cyrulski cyrulo at gmail.com
Thu Apr 12 03:25:45 CEST 2007


Hello,

I designed my own board based on AT91RM9200DK but used different flash -
AT49BV322D atmel flash.
I've downloaded uboot-1.1.5 with atmel patch already apllied and have there
something in flash.c concernig this flash memory.
I chose target board and compilled uboot properly, it works fine but still
doesn't detect my flash and I'm unable to do anything with it.
Maybe there is something missing in the flash.c source code. If someone is
experienced in this will apreciate any help.

best regards
Cyrul

here's where  flash.c  source code, which i got varies from default
at91rm9200dk_config in uboot 1.1.5 source code:


/* Flash Organization Structure */
typedef struct OrgDef
{
	unsigned int sector_number;
	unsigned int sector_size;
} OrgDef;


/* Flash Organizations */
OrgDef OrgAT49BV16x4[] =
{
	{  8,  8*1024 },	/*   8 *  8 kBytes sectors */
	{  2, 32*1024 },	/*   2 * 32 kBytes sectors */
	{ 30, 64*1024 },	/*  30 * 64 kBytes sectors */
};

OrgDef OrgAT49BV16x4A[] =
{
	{  8,  8*1024 },	/*   8 *  8 kBytes sectors */
	{ 31, 64*1024 },	/*  31 * 64 kBytes sectors */
};

OrgDef OrgAT49BV322D[] =
{
	{   8,  8*1024 },	/*   8 *  8 kBytes sectors */
	{  63, 64*1024 },	/* 127 * 64 kBytes sectors */
};

OrgDef OrgAT49BV6416[] =
{
	{   8,  8*1024 },	/*   8 *  8 kBytes sectors */
	{ 127, 64*1024 },	/* 127 * 64 kBytes sectors */
};

flash_info_t    flash_info[CFG_MAX_FLASH_BANKS];


/* AT49BV1614A Codes */
#define FLASH_CODE1		0xAA
#define FLASH_CODE2		0x55
#define ID_IN_CODE		0x90
#define ID_OUT_CODE		0xF0


#define CMD_READ_ARRAY		0x00F0
#define CMD_UNLOCK1		0x00AA
#define CMD_UNLOCK2		0x0055
#define CMD_ERASE_SETUP		0x0080
#define CMD_ERASE_CONFIRM	0x0030
#define CMD_PROGRAM		0x00A0
#define CMD_UNLOCK_BYPASS	0x0020
#define CMD_SECTOR_UNLOCK	0x0070

#define MEM_FLASH_ADDR1		(*(volatile u16 *)(CFG_FLASH_BASE + (0x00005555<<1)))
#define MEM_FLASH_ADDR2		(*(volatile u16 *)(CFG_FLASH_BASE + (0x00002AAA<<1)))

#define BIT_ERASE_DONE		0x0080
#define BIT_RDY_MASK		0x0080
#define BIT_PROGRAM_ERROR	0x0020
#define BIT_TIMEOUT		0x80000000 /* our flag */

#define READY 1
#define ERR   2
#define TMO   4

/*-----------------------------------------------------------------------
 */
void flash_identification (flash_info_t * info)
{
	volatile u16 manuf_code, device_code, add_device_code;

	MEM_FLASH_ADDR1 = FLASH_CODE1;
	MEM_FLASH_ADDR2 = FLASH_CODE2;
	MEM_FLASH_ADDR1 = ID_IN_CODE;

	manuf_code = *(volatile u16 *) CFG_FLASH_BASE;
	device_code = *(volatile u16 *) (CFG_FLASH_BASE + 2);
	add_device_code = *(volatile u16 *) (CFG_FLASH_BASE + (3 << 1));

	MEM_FLASH_ADDR1 = FLASH_CODE1;
	MEM_FLASH_ADDR2 = FLASH_CODE2;
	MEM_FLASH_ADDR1 = ID_OUT_CODE;

#ifdef	CFG_IGNORE_PARFLASH
	info->flash_id = FLASH_UNKNOWN;
	printf ("Parallel flash ignored\n");
#else
	if(manuf_code == (ATM_MANUFACT & FLASH_VENDMASK)) {
		/* Vendor type */
		info->flash_id = ATM_MANUFACT & FLASH_VENDMASK;
		printf ("Atmel: ");
	} else {
		/* Make illegal device doe*/
		printf ("Unknown Vendor: ");
		device_code = 0;
	}

	/* 16 Mbit Devices (Not recommended for new design) */	
	if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV1614 & FLASH_TYPEMASK)) {

		if ((add_device_code & FLASH_TYPEMASK) ==
			(ATM_ID_BV1614A & FLASH_TYPEMASK)) {
			info->flash_id |= ATM_ID_BV1614A & FLASH_TYPEMASK;
			printf ("AT49BV1614A (16Mbit)\n");
		} else {				/* AT49BV1614 Flash */
			info->flash_id |= ATM_ID_BV1614 & FLASH_TYPEMASK;
			printf ("AT49BV1614 (16Mbit)\n");
		}

	/* 16 Mbit Devices (Recommended for new design) */	
	} else if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV160D &
FLASH_TYPEMASK)) {
		info->flash_id |= ATM_ID_BV160D & FLASH_TYPEMASK;
		printf ("AT49BV160D (16Mbit)\n");
	} else if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV160DT &
FLASH_TYPEMASK)) {
		info->flash_id = FLASH_UNKNOWN;
	//	info->flash_id |= ATM_ID_BV160DT & FLASH_TYPEMASK;
		printf ("AT49BV160DT (16Mbit) - Not Yet Supported \n");
	} else if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV163D &
FLASH_TYPEMASK)) {
		info->flash_id |= ATM_ID_BV163D & FLASH_TYPEMASK;
		printf ("AT49BV163D (16Mbit)\n");
	} else if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV163DT &
FLASH_TYPEMASK)) {
		info->flash_id |= ATM_ID_BV163DT & FLASH_TYPEMASK;
		printf ("AT49BV163DT (16Mbit) - Not Yet Supported\n");

	/* 32 Mbit Devices (Not recommended for new design) */	
	} else if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV322A &
FLASH_TYPEMASK)) {
		info->flash_id |= ATM_ID_BV322A & FLASH_TYPEMASK;
		printf ("AT49BV322A (64Mbit)\n");

	/* 32 Mbit Devices (Recommended for new design) */
	} else if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV320D &
FLASH_TYPEMASK)) {
		info->flash_id |= ATM_ID_BV320D & FLASH_TYPEMASK;
		info->flash_id = FLASH_UNKNOWN;
		printf ("AT49BV320D (64Mbit) - Not Yet Supported\n");
	} else if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV320DT &
FLASH_TYPEMASK)) {
		info->flash_id |= ATM_ID_BV320DT & FLASH_TYPEMASK;
		info->flash_id = FLASH_UNKNOWN;
		printf ("AT49BV320DT (64Mbit) - Not Yet Supported\n");
	} else if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV322D &
FLASH_TYPEMASK)) {
		info->flash_id |= ATM_ID_BV322D & FLASH_TYPEMASK;
		printf ("AT49BV322D (64Mbit)\n");
	} else if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV322DT &
FLASH_TYPEMASK)) {
		info->flash_id |= ATM_ID_BV322DT & FLASH_TYPEMASK;
		info->flash_id = FLASH_UNKNOWN;
		printf ("AT49BV322DT (64Mbit) - Not Yet Supported\n");

	/* 64 Mbit Devices (Not recommended for new design) */	
	} else if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV6416 &
FLASH_TYPEMASK)) {
		info->flash_id |= ATM_ID_BV6416 & FLASH_TYPEMASK;
		printf ("AT49BV6416 (64Mbit)\n");
	} else if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV6416T &
FLASH_TYPEMASK)) {
		info->flash_id |= ATM_ID_BV6416T & FLASH_TYPEMASK;
		info->flash_id = FLASH_UNKNOWN;
		printf ("AT49BV6416 (64Mbit) - Top Boot Not Yet Supported\n");
	} else if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV6416C &
FLASH_TYPEMASK)) {
		info->flash_id |= ATM_ID_BV6416C & FLASH_TYPEMASK;
		info->flash_id = FLASH_UNKNOWN;
		printf ("AT49BV6416C (64Mbit) - Not Yet Supported\n");
	} else if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV6416CT &
FLASH_TYPEMASK)) {
		info->flash_id |= ATM_ID_BV6416CT & FLASH_TYPEMASK;
		info->flash_id = FLASH_UNKNOWN;
		printf ("AT49BV6416CT (64Mbit) - Top Boot Not Yet Supported\n");

	/* 64 Mbit Devices (Recommended for new design) */	
	} else if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV640D &
FLASH_TYPEMASK)) {
		info->flash_id |= ATM_ID_BV640D & FLASH_TYPEMASK;
		info->flash_id = FLASH_UNKNOWN;
		printf ("AT49BV640D (64Mbit) - Not Yet Supported\n");
	} else if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV640DT &
FLASH_TYPEMASK)) {
		info->flash_id |= ATM_ID_BV640DT & FLASH_TYPEMASK;
		info->flash_id = FLASH_UNKNOWN;
		printf ("AT49BV640DT (64Mbit) - Top Boot Not Yet Supported\n");
	} else if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV642D &
FLASH_TYPEMASK)) {
		info->flash_id |= ATM_ID_BV642D & FLASH_TYPEMASK;
		printf ("AT49BV642D (64Mbit)\n");
	} else if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV642DT &
FLASH_TYPEMASK)) {
		info->flash_id |= ATM_ID_BV642DT & FLASH_TYPEMASK;
		info->flash_id = FLASH_UNKNOWN;
		printf ("AT49BV642DT (64Mbit) - Top Boot Not Yet Supported\n");
	} else if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV6404 &
FLASH_TYPEMASK)) {
		info->flash_id |= ATM_ID_BV6404 & FLASH_TYPEMASK;
		info->flash_id = FLASH_UNKNOWN;
		printf ("AT49BV6404 (64Mbit - Not Yet Supported)\n");
	} else {
		info->flash_id = FLASH_UNKNOWN;
		printf ("UNKNOWN device or not present\n");
	}
#endif
}

ushort flash_number_sector(OrgDef *pOrgDef, unsigned int nb_blocks)
{
	int i, nb_sectors = 0;

	for (i=0; i<nb_blocks; i++){
		nb_sectors += pOrgDef[i].sector_number;
	}

	return nb_sectors;
}

void flash_unlock_sector(flash_info_t * info, unsigned int sector)
{
	volatile u16 *addr = (volatile u16 *) (info->start[sector]);

	MEM_FLASH_ADDR1 = CMD_UNLOCK1;
	*addr = CMD_SECTOR_UNLOCK;
}


ulong flash_init (void)
{
	int i, j, k;
	unsigned int flash_nb_blocks, sector;
	unsigned int start_address;
	unsigned int unlock;
	OrgDef *pOrgDef;

	ulong size = 0;


	for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
		ulong flashbase = 0;
		unlock = 0;

		flash_identification (&flash_info[i]);

		if ((flash_info[i].flash_id & FLASH_TYPEMASK) ==
			(ATM_ID_BV1614 & FLASH_TYPEMASK)) {	/* AT49BV1614 Flash */

			pOrgDef = OrgAT49BV16x4;
			flash_nb_blocks = sizeof (OrgAT49BV16x4) / sizeof (OrgDef);
		} else if ((flash_info[i].flash_id & FLASH_TYPEMASK) ==
			(ATM_ID_BV1614A & FLASH_TYPEMASK)){	/* AT49BV1614A Flash */

			pOrgDef = OrgAT49BV16x4A;
			flash_nb_blocks = sizeof (OrgAT49BV16x4A) / sizeof (OrgDef);
		} else if ((flash_info[i].flash_id & FLASH_TYPEMASK) ==
			(ATM_ID_BV163D & FLASH_TYPEMASK)){	/* AT49BV163D Flash */

			pOrgDef = OrgAT49BV16x4A;
			flash_nb_blocks = sizeof (OrgAT49BV16x4A) / sizeof (OrgDef);
		} else if ((flash_info[i].flash_id & FLASH_TYPEMASK) ==
			(ATM_ID_BV322A & FLASH_TYPEMASK)){	/* AT49BV322D Flash */

			pOrgDef = OrgAT49BV322D;
			flash_nb_blocks = sizeof (OrgAT49BV16x4A) / sizeof (OrgDef);
		} else if ((flash_info[i].flash_id & FLASH_TYPEMASK) ==
			(ATM_ID_BV322D & FLASH_TYPEMASK)){	/* AT49BV322D Flash */
			unlock = 1;
			pOrgDef = OrgAT49BV322D;
			flash_nb_blocks = sizeof (OrgAT49BV16x4A) / sizeof (OrgDef);
		} else if ((flash_info[i].flash_id & FLASH_TYPEMASK) ==
			(ATM_ID_BV6416 & FLASH_TYPEMASK)){	/* AT49BV6416 Flash */
			unlock = 1;
			pOrgDef = OrgAT49BV6416;
			flash_nb_blocks = sizeof (OrgAT49BV6416) / sizeof (OrgDef);
		} else if ((flash_info[i].flash_id & FLASH_TYPEMASK) ==
			(ATM_ID_BV642D & FLASH_TYPEMASK)){	/* AT49BV642D Flash */
			unlock = 1;
			pOrgDef = OrgAT49BV6416;
			flash_nb_blocks = sizeof (OrgAT49BV6416) / sizeof (OrgDef);
		} else {
			flash_nb_blocks = 0;
			pOrgDef = OrgAT49BV16x4;
		}

		flash_info[i].sector_count = flash_number_sector(pOrgDef, flash_nb_blocks);
		memset (flash_info[i].protect, 0, flash_info[i].sector_count);

		if (i == 0)
			flashbase = PHYS_FLASH_1;
		else
			panic ("configured too many flash banks!\n");

		sector = 0;
		start_address = flashbase;
		flash_info[i].size = 0;

		for (j = 0; j < flash_nb_blocks; j++) {
			for (k = 0; k < pOrgDef[j].sector_number; k++) {
				flash_info[i].start[sector++] = start_address;
				start_address += pOrgDef[j].sector_size;
				flash_info[i].size += pOrgDef[j].sector_size;
			}
		}

		size += flash_info[i].size;

		if (unlock){
			/* Unlock all sectors at reset */
			for (j=0; j<flash_info[i].sector_count; j++){
				flash_unlock_sector(&flash_info[i], j);
			}
		}
	}

	/* Protect binary boot image */
	flash_protect (FLAG_PROTECT_SET,
		       CFG_FLASH_BASE,
		       CFG_FLASH_BASE + CFG_BOOT_SIZE - 1, &flash_info[0]);

	/* Protect environment variables */
	flash_protect (FLAG_PROTECT_SET,
		       CFG_ENV_ADDR,
		       CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);

	/* Protect U-Boot gzipped image */
	flash_protect (FLAG_PROTECT_SET,
		       CFG_U_BOOT_BASE,
		       CFG_U_BOOT_BASE + CFG_U_BOOT_SIZE - 1, &flash_info[0]);

	return size;
}

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


void flash_print_info (flash_info_t * info)
{
	int i;

	switch (info->flash_id & FLASH_VENDMASK) {
	case (ATM_MANUFACT & FLASH_VENDMASK):
		printf ("Atmel: ");
		break;
	default:
		printf ("Unknown Vendor ");
		break;
	}

	switch (info->flash_id & FLASH_TYPEMASK) {
	case (ATM_ID_BV1614 & FLASH_TYPEMASK):
		printf ("AT49BV1614 (16Mbit)\n");
		break;
	case (ATM_ID_BV1614A & FLASH_TYPEMASK):
		printf ("AT49BV1614A (16Mbit)\n");
		break;
	case (ATM_ID_BV160D & FLASH_TYPEMASK):
		printf ("AT49BV160D  (16Mbit)\n");
		break;
	case (ATM_ID_BV160DT & FLASH_TYPEMASK):
		printf ("AT49BV160DT  (16Mbit)\n");
		break;
	case (ATM_ID_BV163D & FLASH_TYPEMASK):
		printf ("AT49BV163D (16Mbit)\n");
		break;
	case (ATM_ID_BV163DT & FLASH_TYPEMASK):
		printf ("AT49BV163DT (16Mbit)\n");
		break;
#if 0		/* Duplicate with ATM_ID_BV1614A */
	case (ATM_ID_BV322A & FLASH_TYPEMASK):
		printf ("AT49BV322A (32Mbit)\n");
		break;
#endif
	case (ATM_ID_BV322AT & FLASH_TYPEMASK):
		printf ("AT49BV322AT (32Mbit)\n");
		break;
	case (ATM_ID_BV320D & FLASH_TYPEMASK):
		printf ("AT49BV320D  (32Mbit)\n");
		break;
	case (ATM_ID_BV320DT & FLASH_TYPEMASK):
		printf ("AT49BV320DT  (32Mbit)\n");
		break;
	case (ATM_ID_BV322D & FLASH_TYPEMASK):
		printf ("AT49BV322D  (32Mbit)\n");
		break;
	case (ATM_ID_BV322DT & FLASH_TYPEMASK):
		printf ("AT49BV322DT  (32Mbit)\n");
		break;
	case (ATM_ID_BV6416 & FLASH_TYPEMASK):
		printf ("AT49BV6416 (64Mbit)\n");
		break;
	case (ATM_ID_BV6416T & FLASH_TYPEMASK):
		printf ("AT49BV6416T (64Mbit)\n");
		break;
	case (ATM_ID_BV6416C & FLASH_TYPEMASK):
		printf ("AT49BV6416C (64Mbit)\n");
		break;
	case (ATM_ID_BV6416CT & FLASH_TYPEMASK):
		printf ("AT49BV6416CT (64Mbit)\n");
		break;
	case (ATM_ID_BV640D & FLASH_TYPEMASK):
		printf ("AT49BV640D (64Mbit)\n");
		break;
	case (ATM_ID_BV640DT & FLASH_TYPEMASK):
		printf ("AT49BV640DT (64Mbit)\n");
		break;
	case (ATM_ID_BV642D & FLASH_TYPEMASK):
		printf ("AT49BV642C (64Mbit)\n");
		break;
	case (ATM_ID_BV642DT & FLASH_TYPEMASK):
		printf ("AT49BV642DT (64Mbit)\n");
		break;
	default:
		printf ("Unknown Chip Type\n");
		return;
	}

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

	printf ("  Sector Start Addresses:");
	for (i = 0; i < info->sector_count; i++) {
		if ((i % 5) == 0) {
			printf ("\n   ");
		}

		if(info->protect[i] != FLAG_PROTECT_INVALID) {
			printf (" %08lX%s", info->start[i],
				info->protect[i] ? " (RO)" : "     ");
		}
	}
	printf ("\n");
}




More information about the U-Boot mailing list