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 flash.c:
#include <common.h>
ulong myflush(void);
typedef struct OrgDef
{
unsigned
int sector_number;
unsigned int sector_size;
} OrgDef;
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");
}
erase, write_buff, write_word functions are the same - like in other
uboot versions without atmel patch applied