summaryrefslogtreecommitdiff
path: root/board/at91rm9200dk/flash.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/at91rm9200dk/flash.c')
-rw-r--r--board/at91rm9200dk/flash.c98
1 files changed, 70 insertions, 28 deletions
diff --git a/board/at91rm9200dk/flash.c b/board/at91rm9200dk/flash.c
index 9a67755..5220fcf 100644
--- a/board/at91rm9200dk/flash.c
+++ b/board/at91rm9200dk/flash.c
@@ -42,20 +42,22 @@ typedef struct OrgDef
/* Flash Organizations */
OrgDef OrgAT49BV16x4[] =
{
- { 8, 8*1024 }, /* 8 * 8kBytes sectors */
- { 2, 32*1024 }, /* 2 * 32kBytes sectors */
- { 30, 64*1024 } /* 30 * 64kBytes sectors */
+ { 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 * 8kBytes sectors */
- { 31, 64*1024 } /* 31 * 64kBytes sectors */
+ { 8, 8*1024 }, /* 8 * 8 kBytes sectors */
+ { 31, 64*1024 }, /* 31 * 64 kBytes sectors */
};
-
-#define FLASH_BANK_SIZE 0x200000 /* 2 MB */
-#define MAIN_SECT_SIZE 0x10000 /* 64 KB */
+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];
@@ -73,13 +75,11 @@ flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
#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 IDENT_FLASH_ADDR1 (*(volatile u16 *)(CFG_FLASH_BASE + (0x0000555<<1)))
-#define IDENT_FLASH_ADDR2 (*(volatile u16 *)(CFG_FLASH_BASE + (0x0000AAA<<1)))
-
#define BIT_ERASE_DONE 0x0080
#define BIT_RDY_MASK 0x0080
#define BIT_PROGRAM_ERROR 0x0020
@@ -95,17 +95,17 @@ void flash_identification (flash_info_t * info)
{
volatile u16 manuf_code, device_code, add_device_code;
- IDENT_FLASH_ADDR1 = FLASH_CODE1;
- IDENT_FLASH_ADDR2 = FLASH_CODE2;
- IDENT_FLASH_ADDR1 = ID_IN_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));
- IDENT_FLASH_ADDR1 = FLASH_CODE1;
- IDENT_FLASH_ADDR2 = FLASH_CODE2;
- IDENT_FLASH_ADDR1 = ID_OUT_CODE;
+ MEM_FLASH_ADDR1 = FLASH_CODE1;
+ MEM_FLASH_ADDR2 = FLASH_CODE2;
+ MEM_FLASH_ADDR1 = ID_OUT_CODE;
/* Vendor type */
info->flash_id = ATM_MANUFACT & FLASH_VENDMASK;
@@ -117,14 +117,36 @@ void flash_identification (flash_info_t * info)
(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");
}
- } else { /* AT49BV1614 Flash */
- info->flash_id |= ATM_ID_BV1614 & FLASH_TYPEMASK;
- printf ("AT49BV1614 (16Mbit)\n");
+ } else if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV6416 & FLASH_TYPEMASK)) {
+ info->flash_id |= ATM_ID_BV6416 & FLASH_TYPEMASK;
+ printf ("AT49BV6416 (64Mbit)\n");
}
}
+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)
{
@@ -140,23 +162,29 @@ ulong flash_init (void)
flash_identification (&flash_info[i]);
- flash_info[i].size = FLASH_BANK_SIZE;
-
if ((flash_info[i].flash_id & FLASH_TYPEMASK) ==
(ATM_ID_BV1614 & FLASH_TYPEMASK)) {
- flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
- memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
pOrgDef = OrgAT49BV16x4;
flash_nb_blocks = sizeof (OrgAT49BV16x4) / sizeof (OrgDef);
- } else { /* AT49BV1614A Flash */
- flash_info[i].sector_count = CFG_MAX_FLASH_SECT - 1;
- memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT - 1);
+ } 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_BV6416 & FLASH_TYPEMASK)){ /* AT49BV6416 Flash */
+
+ 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
@@ -164,15 +192,26 @@ ulong flash_init (void)
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 ((flash_info[i].flash_id & FLASH_TYPEMASK) ==
+ (ATM_ID_BV6416 & FLASH_TYPEMASK)){ /* AT49BV6416 Flash */
+
+ /* 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 */
@@ -215,6 +254,9 @@ void flash_print_info (flash_info_t * info)
case (ATM_ID_BV1614A & FLASH_TYPEMASK):
printf ("AT49BV1614A (16Mbit)\n");
break;
+ case (ATM_ID_BV6416 & FLASH_TYPEMASK):
+ printf ("AT49BV6416 (64Mbit)\n");
+ break;
default:
printf ("Unknown Chip Type\n");
goto Done;
@@ -234,7 +276,7 @@ void flash_print_info (flash_info_t * info)
}
printf ("\n");
- Done:
+Done: ;
}
/*-----------------------------------------------------------------------