X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fflash%2Fnor%2Fat91sam4.c;h=b8f4e1622cacf89e7db3d5a306a474e85aedabf5;hp=84d09c2117bf0cf6dc7ab9f5c6e2915ccf4eaf1b;hb=20922f47c74b97c5d39f8e3036a107ebfdc7e8c3;hpb=8e44a9663df314ad527cca6687ea362c72e84a3f diff --git a/src/flash/nor/at91sam4.c b/src/flash/nor/at91sam4.c index 84d09c2117..b8f4e1622c 100644 --- a/src/flash/nor/at91sam4.c +++ b/src/flash/nor/at91sam4.c @@ -9,19 +9,17 @@ * (at91sam3x* & at91sam4 support)* * * * * 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 * + * 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. * + * 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., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * ****************************************************************************/ /* Some of the the lower level code was based on code supplied by @@ -67,8 +65,9 @@ #define REG_NAME_WIDTH (12) -/* at91sam4s series (has always one flash bank)*/ +/* at91sam4s/at91sam4e/at91sam4c series (has always one flash bank)*/ #define FLASH_BANK_BASE_S 0x00400000 +#define FLASH_BANK_BASE_C 0x01000000 /* at91sam4sd series (two one flash banks), first bank address */ #define FLASH_BANK0_BASE_SD FLASH_BANK_BASE_S @@ -77,6 +76,10 @@ /* at91sam4sd32x, second bank address */ #define FLASH_BANK1_BASE_2048K_SD (FLASH_BANK0_BASE_SD+(2048*1024/2)) +/* at91sam4c32x, first and second bank address */ +#define FLASH_BANK0_BASE_C32 FLASH_BANK_BASE_C +#define FLASH_BANK1_BASE_C32 (FLASH_BANK_BASE_C+(2048*1024/2)) + #define AT91C_EFC_FCMD_GETD (0x0) /* (EFC) Get Flash Descriptor */ #define AT91C_EFC_FCMD_WP (0x1) /* (EFC) Write Page */ #define AT91C_EFC_FCMD_WPL (0x2) /* (EFC) Write Page and Lock */ @@ -253,20 +256,671 @@ static struct sam4_chip *get_current_sam4(struct command_context *cmd_ctx) return NULL; } -/*The actual sector size of the SAM4S flash memory is 65536 bytes. 16 sectors for a 1024KB device*/ -/*The lockregions are 8KB per lock region, with a 1024KB device having 128 lock regions. */ -/*For the best results, nsectors are thus set to the amount of lock regions, and the sector_size*/ -/*set to the lock region size. Page erases are used to erase 8KB sections when programming*/ +/*The actual sector size of the SAM4S flash memory is 65536 bytes. 16 sectors for a 1024KB device*/ +/*The lockregions are 8KB per lock region, with a 1024KB device having 128 lock regions. */ +/*For the best results, nsectors are thus set to the amount of lock regions, and the sector_size*/ +/*set to the lock region size. Page erases are used to erase 8KB sections when programming*/ + +/* these are used to *initialize* the "pChip->details" structure. */ +static const struct sam4_chip_details all_sam4_details[] = { + /* Start at91sam4c* series */ + /* at91sam4c32e - LQFP144 */ + { + .chipid_cidr = 0xA66D0EE0, + .name = "at91sam4c32e", + .total_flash_size = 2024 * 1024, + .total_sram_size = 256 * 1024, + .n_gpnvms = 3, + .n_banks = 2, +/* .bank[0] = { */ + { + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK0_BASE_C32, + .controller_address = 0x400e0a00, + .flash_wait_states = 5, + .present = 1, + .size_bytes = 1024 * 1024, + .nsectors = 128, + .sector_size = 8192, + .page_size = 512, + }, +/* .bank[1] = { */ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 1, + .base_address = FLASH_BANK1_BASE_C32, + .controller_address = 0x400e0c00, + .flash_wait_states = 5, + .present = 1, + .size_bytes = 1024 * 1024, + .nsectors = 128, + .sector_size = 8192, + .page_size = 512, + }, + }, + }, + /* at91sam4c32c - LQFP100 */ + { + .chipid_cidr = 0xA64D0EE0, + .name = "at91sam4c32c", + .total_flash_size = 2024 * 1024, + .total_sram_size = 256 * 1024, + .n_gpnvms = 3, + .n_banks = 2, +/* .bank[0] = { */ + { + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK0_BASE_C32, + .controller_address = 0x400e0a00, + .flash_wait_states = 5, + .present = 1, + .size_bytes = 1024 * 1024, + .nsectors = 128, + .sector_size = 8192, + .page_size = 512, + }, +/* .bank[1] = { */ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 1, + .base_address = FLASH_BANK1_BASE_C32, + .controller_address = 0x400e0c00, + .flash_wait_states = 5, + .present = 1, + .size_bytes = 1024 * 1024, + .nsectors = 128, + .sector_size = 8192, + .page_size = 512, + }, + }, + }, + /* at91sam4c16c - LQFP100 */ + { + .chipid_cidr = 0xA64C0CE0, + .name = "at91sam4c16c", + .total_flash_size = 1024 * 1024, + .total_sram_size = 128 * 1024, + .n_gpnvms = 2, + .n_banks = 1, + { +/* .bank[0] = {*/ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK_BASE_C, + .controller_address = 0x400e0a00, + .flash_wait_states = 5, + .present = 1, + .size_bytes = 1024 * 1024, + .nsectors = 128, + .sector_size = 8192, + .page_size = 512, + }, +/* .bank[1] = {*/ + { + .present = 0, + .probed = 0, + .bank_number = 1, + + }, + }, + }, + /* at91sam4c8c - LQFP100 */ + { + .chipid_cidr = 0xA64C0AE0, + .name = "at91sam4c8c", + .total_flash_size = 512 * 1024, + .total_sram_size = 128 * 1024, + .n_gpnvms = 2, + .n_banks = 1, + { +/* .bank[0] = {*/ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK_BASE_C, + .controller_address = 0x400e0a00, + .flash_wait_states = 5, + .present = 1, + .size_bytes = 512 * 1024, + .nsectors = 64, + .sector_size = 8192, + .page_size = 512, + }, +/* .bank[1] = {*/ + { + .present = 0, + .probed = 0, + .bank_number = 1, + + }, + }, + }, + /* at91sam4c4c (rev B) - LQFP100 */ + { + .chipid_cidr = 0xA64C0CE5, + .name = "at91sam4c4c", + .total_flash_size = 256 * 1024, + .total_sram_size = 128 * 1024, + .n_gpnvms = 2, + .n_banks = 1, + { +/* .bank[0] = {*/ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK_BASE_C, + .controller_address = 0x400e0a00, + .flash_wait_states = 5, + .present = 1, + .size_bytes = 256 * 1024, + .nsectors = 32, + .sector_size = 8192, + .page_size = 512, + }, +/* .bank[1] = {*/ + { + .present = 0, + .probed = 0, + .bank_number = 1, + + }, + }, + }, + + /* Start at91sam4e* series */ + /*atsam4e16e - LQFP144/LFBGA144*/ + { + .chipid_cidr = 0xA3CC0CE0, + .name = "at91sam4e16e", + .total_flash_size = 1024 * 1024, + .total_sram_size = 128 * 1024, + .n_gpnvms = 2, + .n_banks = 1, + { +/* .bank[0] = {*/ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK_BASE_S, + .controller_address = 0x400e0a00, + .flash_wait_states = 5, + .present = 1, + .size_bytes = 1024 * 1024, + .nsectors = 128, + .sector_size = 8192, + .page_size = 512, + }, +/* .bank[1] = {*/ + { + .present = 0, + .probed = 0, + .bank_number = 1, + + }, + }, + }, + + /* Start at91sam4n* series */ + /*atsam4n8a - LQFP48/QFN48*/ + { + .chipid_cidr = 0x293B0AE0, + .name = "at91sam4n8a", + .total_flash_size = 512 * 1024, + .total_sram_size = 64 * 1024, + .n_gpnvms = 2, + .n_banks = 1, + { +/* .bank[0] = {*/ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK_BASE_S, + .controller_address = 0x400e0a00, + .flash_wait_states = 5, + .present = 1, + .size_bytes = 512 * 1024, + .nsectors = 64, + .sector_size = 8192, + .page_size = 512, + }, +/* .bank[1] = {*/ + { + .present = 0, + .probed = 0, + .bank_number = 1, + + }, + }, + }, + /*atsam4n8b - LQFP64/QFN64*/ + { + .chipid_cidr = 0x294B0AE0, + .name = "at91sam4n8b", + .total_flash_size = 512 * 1024, + .total_sram_size = 64 * 1024, + .n_gpnvms = 2, + .n_banks = 1, + { +/* .bank[0] = {*/ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK_BASE_S, + .controller_address = 0x400e0a00, + .flash_wait_states = 5, + .present = 1, + .size_bytes = 512 * 1024, + .nsectors = 64, + .sector_size = 8192, + .page_size = 512, + }, +/* .bank[1] = {*/ + { + .present = 0, + .probed = 0, + .bank_number = 1, + + }, + }, + }, + /*atsam4n8c - LQFP100/TFBGA100/VFBGA100*/ + { + .chipid_cidr = 0x295B0AE0, + .name = "at91sam4n8c", + .total_flash_size = 512 * 1024, + .total_sram_size = 64 * 1024, + .n_gpnvms = 2, + .n_banks = 1, + { +/* .bank[0] = {*/ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK_BASE_S, + .controller_address = 0x400e0a00, + .flash_wait_states = 5, + .present = 1, + .size_bytes = 512 * 1024, + .nsectors = 64, + .sector_size = 8192, + .page_size = 512, + }, +/* .bank[1] = {*/ + { + .present = 0, + .probed = 0, + .bank_number = 1, + + }, + }, + }, + /*atsam4n16b - LQFP64/QFN64*/ + { + .chipid_cidr = 0x29460CE0, + .name = "at91sam4n16b", + .total_flash_size = 1024 * 1024, + .total_sram_size = 80 * 1024, + .n_gpnvms = 2, + .n_banks = 1, + { +/* .bank[0] = {*/ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK_BASE_S, + .controller_address = 0x400e0a00, + .flash_wait_states = 5, + .present = 1, + .size_bytes = 1024 * 1024, + .nsectors = 128, + .sector_size = 8192, + .page_size = 512, + }, +/* .bank[1] = {*/ + { + .present = 0, + .probed = 0, + .bank_number = 1, + + }, + }, + }, + /*atsam4n16c - LQFP100/TFBGA100/VFBGA100*/ + { + .chipid_cidr = 0x29560CE0, + .name = "at91sam4n16c", + .total_flash_size = 1024 * 1024, + .total_sram_size = 80 * 1024, + .n_gpnvms = 2, + .n_banks = 1, + { +/* .bank[0] = {*/ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK_BASE_S, + .controller_address = 0x400e0a00, + .flash_wait_states = 5, + .present = 1, + .size_bytes = 1024 * 1024, + .nsectors = 128, + .sector_size = 8192, + .page_size = 512, + }, +/* .bank[1] = {*/ + { + .present = 0, + .probed = 0, + .bank_number = 1, + + }, + }, + }, + + /* Start at91sam4s* series */ + /*atsam4s16c - LQFP100/BGA100*/ + { + .chipid_cidr = 0x28AC0CE0, + .name = "at91sam4s16c", + .total_flash_size = 1024 * 1024, + .total_sram_size = 128 * 1024, + .n_gpnvms = 2, + .n_banks = 1, + { +/* .bank[0] = {*/ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK_BASE_S, + .controller_address = 0x400e0a00, + .flash_wait_states = 5, + .present = 1, + .size_bytes = 1024 * 1024, + .nsectors = 128, + .sector_size = 8192, + .page_size = 512, + }, +/* .bank[1] = {*/ + { + .present = 0, + .probed = 0, + .bank_number = 1, + + }, + }, + }, + /*at91sam4sa16c - TFBGA100/VFBGA100/LQFP100*/ + { + .chipid_cidr = 0x28a70ce0, + .name = "at91sam4sa16c", + .total_flash_size = 1024 * 1024, + .total_sram_size = 160 * 1024, + .n_gpnvms = 2, + .n_banks = 1, + +/* .bank[0] = { */ + { + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK_BASE_S, + .controller_address = 0x400e0a00, + .flash_wait_states = 5, + .present = 1, + .size_bytes = 1024 * 1024, + .nsectors = 128, + .sector_size = 8192, + .page_size = 512, + }, +/* .bank[1] = {*/ + { + .present = 0, + .probed = 0, + .bank_number = 1, + + }, + }, + }, + /*atsam4s16b - LQFP64/QFN64/WLCSP64*/ + { + .chipid_cidr = 0x289C0CE0, + .name = "at91sam4s16b", + .total_flash_size = 1024 * 1024, + .total_sram_size = 128 * 1024, + .n_gpnvms = 2, + .n_banks = 1, + { +/* .bank[0] = {*/ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK_BASE_S, + .controller_address = 0x400e0a00, + .flash_wait_states = 5, + .present = 1, + .size_bytes = 1024 * 1024, + .nsectors = 128, + .sector_size = 8192, + .page_size = 512, + }, +/* .bank[1] = {*/ + { + .present = 0, + .probed = 0, + .bank_number = 1, + + }, + }, + }, + /*atsam4sa16b - LQFP64/QFN64*/ + { + .chipid_cidr = 0x28970CE0, + .name = "at91sam4sa16b", + .total_flash_size = 1024 * 1024, + .total_sram_size = 160 * 1024, + .n_gpnvms = 2, + .n_banks = 1, + { +/* .bank[0] = {*/ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK_BASE_S, + .controller_address = 0x400e0a00, + .flash_wait_states = 5, + .present = 1, + .size_bytes = 1024 * 1024, + .nsectors = 128, + .sector_size = 8192, + .page_size = 512, + }, +/* .bank[1] = {*/ + { + .present = 0, + .probed = 0, + .bank_number = 1, + + }, + }, + }, + /*atsam4s16a - LQFP48/QFN48*/ + { + .chipid_cidr = 0x288C0CE0, + .name = "at91sam4s16a", + .total_flash_size = 1024 * 1024, + .total_sram_size = 128 * 1024, + .n_gpnvms = 2, + .n_banks = 1, + { +/* .bank[0] = {*/ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK_BASE_S, + .controller_address = 0x400e0a00, + .flash_wait_states = 5, + .present = 1, + .size_bytes = 1024 * 1024, + .nsectors = 128, + .sector_size = 8192, + .page_size = 512, + }, +/* .bank[1] = {*/ + { + .present = 0, + .probed = 0, + .bank_number = 1, + + }, + }, + }, + /*atsam4s8c - LQFP100/BGA100*/ + { + .chipid_cidr = 0x28AC0AE0, + .name = "at91sam4s8c", + .total_flash_size = 512 * 1024, + .total_sram_size = 128 * 1024, + .n_gpnvms = 2, + .n_banks = 1, + { +/* .bank[0] = {*/ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK_BASE_S, + .controller_address = 0x400e0a00, + .flash_wait_states = 5, + .present = 1, + .size_bytes = 512 * 1024, + .nsectors = 64, + .sector_size = 8192, + .page_size = 512, + }, +/* .bank[1] = {*/ + { + .present = 0, + .probed = 0, + .bank_number = 1, + + }, + }, + }, + /*atsam4s8b - LQFP64/QFN64/WLCSP64*/ + { + .chipid_cidr = 0x289C0AE0, + .name = "at91sam4s8b", + .total_flash_size = 512 * 1024, + .total_sram_size = 128 * 1024, + .n_gpnvms = 2, + .n_banks = 1, + { +/* .bank[0] = {*/ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK_BASE_S, + .controller_address = 0x400e0a00, + .flash_wait_states = 5, + .present = 1, + .size_bytes = 512 * 1024, + .nsectors = 64, + .sector_size = 8192, + .page_size = 512, + }, +/* .bank[1] = {*/ + { + .present = 0, + .probed = 0, + .bank_number = 1, + + }, + }, + }, + /*atsam4s8a - LQFP48/BGA48*/ + { + .chipid_cidr = 0x288C0AE0, + .name = "at91sam4s8a", + .total_flash_size = 512 * 1024, + .total_sram_size = 128 * 1024, + .n_gpnvms = 2, + .n_banks = 1, + { +/* .bank[0] = {*/ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK_BASE_S, + .controller_address = 0x400e0a00, + .flash_wait_states = 5, + .present = 1, + .size_bytes = 512 * 1024, + .nsectors = 64, + .sector_size = 8192, + .page_size = 512, + }, +/* .bank[1] = {*/ + { + .present = 0, + .probed = 0, + .bank_number = 1, + + }, + }, + }, -/* these are used to *initialize* the "pChip->details" structure. */ -static const struct sam4_chip_details all_sam4_details[] = { - /* Start at91sam4s* series */ - /*atsam4s16c - LQFP100/BGA100*/ + /*atsam4s4c - LQFP100/BGA100*/ { - .chipid_cidr = 0x28AC0CE0, - .name = "at91sam4s16c", - .total_flash_size = 1024 * 1024, - .total_sram_size = 128 * 1024, + .chipid_cidr = 0x28ab09e0, + .name = "at91sam4s4c", + .total_flash_size = 256 * 1024, + .total_sram_size = 64 * 1024, .n_gpnvms = 2, .n_banks = 1, { @@ -278,10 +932,10 @@ static const struct sam4_chip_details all_sam4_details[] = { .bank_number = 0, .base_address = FLASH_BANK_BASE_S, .controller_address = 0x400e0a00, - .flash_wait_states = 6, /* workaround silicon bug */ + .flash_wait_states = 5, .present = 1, - .size_bytes = 1024 * 1024, - .nsectors = 128, + .size_bytes = 256 * 1024, + .nsectors = 32, .sector_size = 8192, .page_size = 512, }, @@ -294,12 +948,13 @@ static const struct sam4_chip_details all_sam4_details[] = { }, }, }, - /*atsam4s16b - LQFP64/QFN64*/ + + /*atsam4s4b - LQFP64/QFN64/WLCSP64*/ { - .chipid_cidr = 0x289C0CE0, - .name = "at91sam4s16b", - .total_flash_size = 1024 * 1024, - .total_sram_size = 128 * 1024, + .chipid_cidr = 0x289b09e0, + .name = "at91sam4s4b", + .total_flash_size = 256 * 1024, + .total_sram_size = 64 * 1024, .n_gpnvms = 2, .n_banks = 1, { @@ -311,10 +966,10 @@ static const struct sam4_chip_details all_sam4_details[] = { .bank_number = 0, .base_address = FLASH_BANK_BASE_S, .controller_address = 0x400e0a00, - .flash_wait_states = 6, /* workaround silicon bug */ + .flash_wait_states = 5, .present = 1, - .size_bytes = 1024 * 1024, - .nsectors = 128, + .size_bytes = 256 * 1024, + .nsectors = 32, .sector_size = 8192, .page_size = 512, }, @@ -327,12 +982,13 @@ static const struct sam4_chip_details all_sam4_details[] = { }, }, }, - /*atsam4s16a - LQFP48/QFN48*/ + + /*atsam4s4a - LQFP48/QFN48*/ { - .chipid_cidr = 0x288C0CE0, - .name = "at91sam4s16a", - .total_flash_size = 1024 * 1024, - .total_sram_size = 128 * 1024, + .chipid_cidr = 0x288b09e0, + .name = "at91sam4s4a", + .total_flash_size = 256 * 1024, + .total_sram_size = 64 * 1024, .n_gpnvms = 2, .n_banks = 1, { @@ -344,10 +1000,10 @@ static const struct sam4_chip_details all_sam4_details[] = { .bank_number = 0, .base_address = FLASH_BANK_BASE_S, .controller_address = 0x400e0a00, - .flash_wait_states = 6, /* workaround silicon bug */ + .flash_wait_states = 5, .present = 1, - .size_bytes = 1024 * 1024, - .nsectors = 128, + .size_bytes = 256 * 1024, + .nsectors = 32, .sector_size = 8192, .page_size = 512, }, @@ -360,12 +1016,13 @@ static const struct sam4_chip_details all_sam4_details[] = { }, }, }, - /*atsam4s8c - LQFP100/BGA100*/ + + /*atsam4s2c - LQFP100/BGA100*/ { - .chipid_cidr = 0x28AC0AE0, - .name = "at91sam4s8c", - .total_flash_size = 512 * 1024, - .total_sram_size = 128 * 1024, + .chipid_cidr = 0x28ab07e0, + .name = "at91sam4s2c", + .total_flash_size = 128 * 1024, + .total_sram_size = 64 * 1024, .n_gpnvms = 2, .n_banks = 1, { @@ -377,10 +1034,10 @@ static const struct sam4_chip_details all_sam4_details[] = { .bank_number = 0, .base_address = FLASH_BANK_BASE_S, .controller_address = 0x400e0a00, - .flash_wait_states = 6, /* workaround silicon bug */ + .flash_wait_states = 5, .present = 1, - .size_bytes = 512 * 1024, - .nsectors = 64, + .size_bytes = 128 * 1024, + .nsectors = 16, .sector_size = 8192, .page_size = 512, }, @@ -393,12 +1050,13 @@ static const struct sam4_chip_details all_sam4_details[] = { }, }, }, - /*atsam4s8b - LQFP64/BGA64*/ + + /*atsam4s2b - LQPF64/QFN64/WLCSP64*/ { - .chipid_cidr = 0x289C0AE0, - .name = "at91sam4s8b", - .total_flash_size = 512 * 1024, - .total_sram_size = 128 * 1024, + .chipid_cidr = 0x289b07e0, + .name = "at91sam4s2b", + .total_flash_size = 128 * 1024, + .total_sram_size = 64 * 1024, .n_gpnvms = 2, .n_banks = 1, { @@ -410,10 +1068,10 @@ static const struct sam4_chip_details all_sam4_details[] = { .bank_number = 0, .base_address = FLASH_BANK_BASE_S, .controller_address = 0x400e0a00, - .flash_wait_states = 6, /* workaround silicon bug */ + .flash_wait_states = 5, .present = 1, - .size_bytes = 512 * 1024, - .nsectors = 64, + .size_bytes = 128 * 1024, + .nsectors = 16, .sector_size = 8192, .page_size = 512, }, @@ -426,12 +1084,13 @@ static const struct sam4_chip_details all_sam4_details[] = { }, }, }, - /*atsam4s8a - LQFP48/BGA48*/ + + /*atsam4s2a - LQFP48/QFN48*/ { - .chipid_cidr = 0x288C0AE0, - .name = "at91sam4s8a", - .total_flash_size = 512 * 1024, - .total_sram_size = 128 * 1024, + .chipid_cidr = 0x288b07e0, + .name = "at91sam4s2a", + .total_flash_size = 128 * 1024, + .total_sram_size = 64 * 1024, .n_gpnvms = 2, .n_banks = 1, { @@ -443,10 +1102,10 @@ static const struct sam4_chip_details all_sam4_details[] = { .bank_number = 0, .base_address = FLASH_BANK_BASE_S, .controller_address = 0x400e0a00, - .flash_wait_states = 6, /* workaround silicon bug */ + .flash_wait_states = 5, .present = 1, - .size_bytes = 512 * 1024, - .nsectors = 64, + .size_bytes = 128 * 1024, + .nsectors = 16, .sector_size = 8192, .page_size = 512, }, @@ -460,7 +1119,7 @@ static const struct sam4_chip_details all_sam4_details[] = { }, }, - /*at91sam4sd32c*/ + /*at91sam4sd32c - LQFP100/BGA100*/ { .chipid_cidr = 0x29a70ee0, .name = "at91sam4sd32c", @@ -478,7 +1137,51 @@ static const struct sam4_chip_details all_sam4_details[] = { .bank_number = 0, .base_address = FLASH_BANK0_BASE_SD, .controller_address = 0x400e0a00, - .flash_wait_states = 6, /* workaround silicon bug */ + .flash_wait_states = 5, + .present = 1, + .size_bytes = 1024 * 1024, + .nsectors = 128, + .sector_size = 8192, + .page_size = 512, + }, + +/* .bank[1] = { */ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 1, + .base_address = FLASH_BANK1_BASE_2048K_SD, + .controller_address = 0x400e0c00, + .flash_wait_states = 5, + .present = 1, + .size_bytes = 1024 * 1024, + .nsectors = 128, + .sector_size = 8192, + .page_size = 512, + }, + }, + }, + + /*at91sam4sd32b - LQFP64/BGA64*/ + { + .chipid_cidr = 0x29970ee0, + .name = "at91sam4sd32b", + .total_flash_size = 2048 * 1024, + .total_sram_size = 160 * 1024, + .n_gpnvms = 3, + .n_banks = 2, + +/* .bank[0] = { */ + { + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK0_BASE_SD, + .controller_address = 0x400e0a00, + .flash_wait_states = 5, .present = 1, .size_bytes = 1024 * 1024, .nsectors = 128, @@ -494,7 +1197,7 @@ static const struct sam4_chip_details all_sam4_details[] = { .bank_number = 1, .base_address = FLASH_BANK1_BASE_2048K_SD, .controller_address = 0x400e0c00, - .flash_wait_states = 6, /* workaround silicon bug */ + .flash_wait_states = 5, .present = 1, .size_bytes = 1024 * 1024, .nsectors = 128, @@ -504,10 +1207,98 @@ static const struct sam4_chip_details all_sam4_details[] = { }, }, - /* at91samg53n19 */ + /*at91sam4sd16c - LQFP100/BGA100*/ + { + .chipid_cidr = 0x29a70ce0, + .name = "at91sam4sd16c", + .total_flash_size = 1024 * 1024, + .total_sram_size = 160 * 1024, + .n_gpnvms = 3, + .n_banks = 2, + +/* .bank[0] = { */ + { + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK0_BASE_SD, + .controller_address = 0x400e0a00, + .flash_wait_states = 5, + .present = 1, + .size_bytes = 512 * 1024, + .nsectors = 64, + .sector_size = 8192, + .page_size = 512, + }, + +/* .bank[1] = { */ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 1, + .base_address = FLASH_BANK1_BASE_1024K_SD, + .controller_address = 0x400e0c00, + .flash_wait_states = 5, + .present = 1, + .size_bytes = 512 * 1024, + .nsectors = 64, + .sector_size = 8192, + .page_size = 512, + }, + }, + }, + + /*at91sam4sd16b - LQFP64/BGA64*/ + { + .chipid_cidr = 0x29970ce0, + .name = "at91sam4sd16b", + .total_flash_size = 1024 * 1024, + .total_sram_size = 160 * 1024, + .n_gpnvms = 3, + .n_banks = 2, + +/* .bank[0] = { */ + { + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK0_BASE_SD, + .controller_address = 0x400e0a00, + .flash_wait_states = 5, + .present = 1, + .size_bytes = 512 * 1024, + .nsectors = 64, + .sector_size = 8192, + .page_size = 512, + }, + +/* .bank[1] = { */ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 1, + .base_address = FLASH_BANK1_BASE_1024K_SD, + .controller_address = 0x400e0c00, + .flash_wait_states = 5, + .present = 1, + .size_bytes = 512 * 1024, + .nsectors = 64, + .sector_size = 8192, + .page_size = 512, + }, + }, + }, + + /* atsamg53n19 */ { .chipid_cidr = 0x247e0ae0, - .name = "at91samg53n19", + .name = "atsamg53n19", .total_flash_size = 512 * 1024, .total_sram_size = 96 * 1024, .n_gpnvms = 2, @@ -522,7 +1313,7 @@ static const struct sam4_chip_details all_sam4_details[] = { .bank_number = 0, .base_address = FLASH_BANK_BASE_S, .controller_address = 0x400e0a00, - .flash_wait_states = 6, /* workaround silicon bug */ + .flash_wait_states = 5, .present = 1, .size_bytes = 512 * 1024, .nsectors = 64, @@ -539,6 +1330,74 @@ static const struct sam4_chip_details all_sam4_details[] = { } }, + /* atsamg55g19 */ + { + .chipid_cidr = 0x24470ae0, + .name = "atsamg55g19", + .total_flash_size = 512 * 1024, + .total_sram_size = 160 * 1024, + .n_gpnvms = 2, + .n_banks = 1, + + { +/* .bank[0] = */ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK_BASE_S, + .controller_address = 0x400e0a00, + .flash_wait_states = 5, + .present = 1, + .size_bytes = 512 * 1024, + .nsectors = 64, + .sector_size = 8192, + .page_size = 512, + }, +/* .bank[1] = */ + { + .present = 0, + .probed = 0, + .bank_number = 1, + }, + } + }, + + /* atsamg55j19 */ + { + .chipid_cidr = 0x24570ae0, + .name = "atsamg55j19", + .total_flash_size = 512 * 1024, + .total_sram_size = 160 * 1024, + .n_gpnvms = 2, + .n_banks = 1, + + { +/* .bank[0] = */ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK_BASE_S, + .controller_address = 0x400e0a00, + .flash_wait_states = 5, + .present = 1, + .size_bytes = 512 * 1024, + .nsectors = 64, + .sector_size = 8192, + .page_size = 512, + }, +/* .bank[1] = */ + { + .present = 0, + .probed = 0, + .bank_number = 1, + }, + } + }, + /* terminate */ { .chipid_cidr = 0, @@ -697,7 +1556,7 @@ static int EFC_PerformCommand(struct sam4_bank_private *pPrivate, int r; uint32_t v; - long long ms_now, ms_end; + int64_t ms_now, ms_end; /* default */ if (status) @@ -1046,14 +1905,14 @@ static uint32_t sam4_reg_fieldname(struct sam4_chip *pChip, static const char _unknown[] = "unknown"; static const char *const eproc_names[] = { - _unknown, /* 0 */ + "Cortex-M7", /* 0 */ "arm946es", /* 1 */ "arm7tdmi", /* 2 */ - "cortex-m3", /* 3 */ + "Cortex-M3", /* 3 */ "arm920t", /* 4 */ "arm926ejs", /* 5 */ - "cortex-a5", /* 6 */ - "cortex-m4", /* 7 */ + "Cortex-A5", /* 6 */ + "Cortex-M4", /* 7 */ _unknown, /* 8 */ _unknown, /* 9 */ _unknown, /* 10 */ @@ -1074,7 +1933,7 @@ static const char *const nvpsize[] = { "64K bytes", /* 5 */ _unknown, /* 6 */ "128K bytes", /* 7 */ - _unknown, /* 8 */ + "160K bytes", /* 8 */ "256K bytes", /* 9 */ "512K bytes", /* 10 */ _unknown, /* 11 */ @@ -1111,16 +1970,21 @@ static const struct archnames { unsigned value; const char *name; } archnames[] { 0x37, "CAP7 Series" }, { 0x39, "CAP9 Series" }, { 0x3B, "CAP11 Series" }, + { 0x3C, "ATSAM4E" }, { 0x40, "AT91x40 Series" }, { 0x42, "AT91x42 Series" }, { 0x43, "SAMG51 Series" }, + { 0x44, "SAMG55 Series (49-pin WLCSP)" }, + { 0x45, "SAMG55 Series (64-pin)" }, { 0x47, "SAMG53 Series" }, { 0x55, "AT91x55 Series" }, { 0x60, "AT91SAM7Axx Series" }, { 0x61, "AT91SAM7AQxx Series" }, { 0x63, "AT91x63 Series" }, + { 0x64, "SAM4CxxC (100-pin version)" }, + { 0x66, "SAM4CxxE (144-pin version)" }, { 0x70, "AT91SAM7Sxx Series" }, { 0x71, "AT91SAM7XCxx Series" }, { 0x72, "AT91SAM7SExx Series" }, @@ -1512,6 +2376,11 @@ static int sam4_GetInfo(struct sam4_chip *pChip) { const struct sam4_reg_list *pReg; uint32_t regval; + int r; + + r = sam4_ReadAllRegs(pChip); + if (r != ERROR_OK) + return r; pReg = &(sam4_all_regs[0]); while (pReg->name) { @@ -1618,15 +2487,17 @@ FLASH_BANK_COMMAND_HANDLER(sam4_flash_bank_command) /* at91sam4s series only has bank 0*/ /* at91sam4sd series has the same address for bank 0 (FLASH_BANK0_BASE_SD)*/ case FLASH_BANK_BASE_S: + case FLASH_BANK_BASE_C: bank->driver_priv = &(pChip->details.bank[0]); bank->bank_number = 0; pChip->details.bank[0].pChip = pChip; pChip->details.bank[0].pBank = bank; break; - /* Bank 1 of at91sam4sd series */ + /* Bank 1 of at91sam4sd/at91sam4c32 series */ case FLASH_BANK1_BASE_1024K_SD: case FLASH_BANK1_BASE_2048K_SD: + case FLASH_BANK1_BASE_C32: bank->driver_priv = &(pChip->details.bank[1]); bank->bank_number = 1; pChip->details.bank[1].pChip = pChip; @@ -1638,6 +2509,22 @@ FLASH_BANK_COMMAND_HANDLER(sam4_flash_bank_command) return ERROR_OK; } +/** + * Remove all chips from the internal list without distingushing which one + * is owned by this bank. This simplification works only for one shot + * deallocation like current flash_free_all_banks() + */ +static void sam4_free_driver_priv(struct flash_bank *bank) +{ + struct sam4_chip *chip = all_sam4_chips; + while (chip) { + struct sam4_chip *next = chip->next; + free(chip); + chip = next; + } + all_sam4_chips = NULL; +} + static int sam4_GetDetails(struct sam4_bank_private *pPrivate) { const struct sam4_chip_details *pDetails; @@ -1662,6 +2549,8 @@ static int sam4_GetDetails(struct sam4_bank_private *pPrivate) pPrivate->pChip->cfg.CHIPID_CIDR); sam4_explain_chipid_cidr(pPrivate->pChip); return ERROR_FAIL; + } else { + LOG_DEBUG("SAM4 Found chip %s, CIDR 0x%08x", pDetails->name, pDetails->chipid_cidr); } /* DANGER: THERE ARE DRAGONS HERE */ @@ -1697,14 +2586,35 @@ static int sam4_GetDetails(struct sam4_bank_private *pPrivate) return ERROR_OK; } -static int _sam4_probe(struct flash_bank *bank, int noise) +static int sam4_info(struct flash_bank *bank, char *buf, int buf_size) +{ + struct sam4_bank_private *pPrivate; + int k = bank->size / 1024; + + pPrivate = get_sam4_bank_private(bank); + if (pPrivate == NULL) { + buf[0] = '\0'; + return ERROR_FAIL; + } + + snprintf(buf, buf_size, + "%s bank %d: %d kB at 0x%08" PRIx32, + pPrivate->pChip->details.name, + pPrivate->bank_number, + k, + bank->base); + + return ERROR_OK; +} + +static int sam4_probe(struct flash_bank *bank) { unsigned x; int r; struct sam4_bank_private *pPrivate; - LOG_DEBUG("Begin: Bank: %d, Noise: %d", bank->bank_number, noise); + LOG_DEBUG("Begin: Bank: %d", bank->bank_number); if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; @@ -1732,6 +2642,7 @@ static int _sam4_probe(struct flash_bank *bank, int noise) for (x = 0; x < SAM4_MAX_FLASH_BANKS; x++) { if (bank->base == pPrivate->pChip->details.bank[x].base_address) { bank->size = pPrivate->pChip->details.bank[x].size_bytes; + LOG_DEBUG("SAM4 Set flash bank to %08X - %08X, idx %d", bank->base, bank->base + bank->size, x); break; } } @@ -1770,14 +2681,15 @@ static int _sam4_probe(struct flash_bank *bank, int noise) return r; } -static int sam4_probe(struct flash_bank *bank) -{ - return _sam4_probe(bank, 1); -} - static int sam4_auto_probe(struct flash_bank *bank) { - return _sam4_probe(bank, 0); + struct sam4_bank_private *pPrivate; + + pPrivate = get_sam4_bank_private(bank); + if (pPrivate && pPrivate->probed) + return ERROR_OK; + + return sam4_probe(bank); } static int sam4_erase(struct flash_bank *bank, int first, int last) @@ -1877,7 +2789,7 @@ static int sam4_page_read(struct sam4_bank_private *pPrivate, unsigned pagenum, return r; } -static int sam4_page_write(struct sam4_bank_private *pPrivate, unsigned pagenum, uint8_t *buf) +static int sam4_page_write(struct sam4_bank_private *pPrivate, unsigned pagenum, const uint8_t *buf) { uint32_t adr; uint32_t status; @@ -1939,7 +2851,7 @@ static int sam4_page_write(struct sam4_bank_private *pPrivate, unsigned pagenum, } static int sam4_write(struct flash_bank *bank, - uint8_t *buffer, + const uint8_t *buffer, uint32_t offset, uint32_t count) { @@ -2318,4 +3230,6 @@ struct flash_driver at91sam4_flash = { .auto_probe = sam4_auto_probe, .erase_check = default_flash_blank_check, .protect_check = sam4_protect_check, + .info = sam4_info, + .free_driver_priv = sam4_free_driver_priv, };