* *
* Copyright (C) 2010 by Olaf Lüke (at91sam3s* support) *
* olaf@uni-paderborn.de *
- * *
- * *
+ * *
+ * Copyright (C) 2011 by Olivier Schonken (at91sam3x* support) * *
+ * and Jim Norris *
* 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 *
* the Free Software Foundation; either version 2 of the License, or *
* 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., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
****************************************************************************/
/* Some of the the lower level code was based on code supplied by
/* at91sam3s series (has always one flash bank) */
#define FLASH_BANK_BASE_S 0x00400000
+/* at91sam3sd series (has always two flash banks) */
+#define FLASH_BANK0_BASE_SD FLASH_BANK_BASE_S
+#define FLASH_BANK1_BASE_512K_SD (FLASH_BANK0_BASE_SD+(512*1024/2))
+
+
/* at91sam3n series (has always one flash bank) */
#define FLASH_BANK_BASE_N 0x00400000
+/* at91sam3a/x series has two flash banks*/
+#define FLASH_BANK0_BASE_AX 0x00080000
+/*Bank 1 of the at91sam3a/x series starts at 0x00080000 + half flash size*/
+#define FLASH_BANK1_BASE_256K_AX 0x000A0000
+#define FLASH_BANK1_BASE_512K_AX 0x000C0000
+
#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 */
#define AT91C_EFC_FCMD_EWP (0x3) /* (EFC) Erase Page and Write Page */
-#define AT91C_EFC_FCMD_EWPL (0x4) /* (EFC) Erase Page and Write Page
- * then Lock */
+#define AT91C_EFC_FCMD_EWPL (0x4) /* (EFC) Erase Page and Write Page then Lock */
#define AT91C_EFC_FCMD_EA (0x5) /* (EFC) Erase All */
-/* cmd6 is not present int he at91sam3u4/2/1 data sheet table 17-2 */
+/* cmd6 is not present in the at91sam3u4/2/1 data sheet table 17-2 */
/* #define AT91C_EFC_FCMD_EPL (0x6) // (EFC) Erase plane? */
-/* cmd7 is not present int he at91sam3u4/2/1 data sheet table 17-2 */
+/* cmd7 is not present in the at91sam3u4/2/1 data sheet table 17-2 */
/* #define AT91C_EFC_FCMD_EPA (0x7) // (EFC) Erase pages? */
#define AT91C_EFC_FCMD_SLB (0x8) /* (EFC) Set Lock Bit */
#define AT91C_EFC_FCMD_CLB (0x9) /* (EFC) Clear Lock Bit */
#define SAM3_CHIPID_CIDR (0x400E0740)
uint32_t CHIPID_CIDR;
+#define SAM3_CHIPID_CIDR2 (0x400E0940) /*SAM3X and SAM3A cidr at this address*/
+ uint32_t CHIPID_CIDR2;
#define SAM3_CHIPID_EXID (0x400E0744)
uint32_t CHIPID_EXID;
+#define SAM3_CHIPID_EXID2 (0x400E0944) /*SAM3X and SAM3A cidr at this address*/
+ uint32_t CHIPID_EXID2;
-#define SAM3_SUPC_CR (0x400E1210)
- uint32_t SUPC_CR;
#define SAM3_PMC_BASE (0x400E0400)
#define SAM3_PMC_SCSR (SAM3_PMC_BASE + 0x0008)
/* so we can find the chip we belong to */
struct sam3_chip *pChip;
- /* so we can find the orginal bank pointer */
+ /* so we can find the original bank pointer */
struct flash_bank *pBank;
unsigned bank_number;
uint32_t controller_address;
struct sam3_chip_details {
/* THERE ARE DRAGONS HERE.. */
/* note: If you add pointers here */
- /* becareful about them as they */
+ /* be careful about them as they */
/* may need to be updated inside */
/* the function: "sam3_GetDetails() */
/* which copy/overwrites the */
/* Note: The preliminary at91sam3s datasheet says on page 302 */
/* that the flash controller is at address 0x400E0800. */
- /* This is _not_ the case, the controller resides at address 0x400e0a0. */
+ /* This is _not_ the case, the controller resides at address 0x400e0a00. */
{
.chipid_cidr = 0x28A00960,
.name = "at91sam3s4c",
},
},
},
+ {
+ .chipid_cidr = 0x298B0A60,
+ .name = "at91sam3sd8a",
+ .total_flash_size = 512 * 1024,
+ .total_sram_size = 64 * 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 = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 256 * 1024,
+ .nsectors = 16,
+ .sector_size = 32768,
+ .page_size = 256,
+ },
+/* .bank[1] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 1,
+ .base_address = FLASH_BANK1_BASE_512K_SD,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 256 * 1024,
+ .nsectors = 16,
+ .sector_size = 32768,
+ .page_size = 256,
+ },
+ },
+ },
+ {
+ .chipid_cidr = 0x299B0A60,
+ .name = "at91sam3sd8b",
+ .total_flash_size = 512 * 1024,
+ .total_sram_size = 64 * 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 = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 256 * 1024,
+ .nsectors = 16,
+ .sector_size = 32768,
+ .page_size = 256,
+ },
+/* .bank[1] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 1,
+ .base_address = FLASH_BANK1_BASE_512K_SD,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 256 * 1024,
+ .nsectors = 16,
+ .sector_size = 32768,
+ .page_size = 256,
+ },
+ },
+ },
+ {
+ .chipid_cidr = 0x29ab0a60,
+ .name = "at91sam3sd8c",
+ .total_flash_size = 512 * 1024,
+ .total_sram_size = 64 * 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 = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 256 * 1024,
+ .nsectors = 16,
+ .sector_size = 32768,
+ .page_size = 256,
+ },
+/* .bank[1] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 1,
+ .base_address = FLASH_BANK1_BASE_512K_SD,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 256 * 1024,
+ .nsectors = 16,
+ .sector_size = 32768,
+ .page_size = 256,
+ },
+ },
+ },
{
.chipid_cidr = 0x288A0760,
.name = "at91sam3s2a",
},
},
},
+ {
+ .chipid_cidr = 0x288B0A60,
+ .name = "at91sam3s8a",
+ .total_flash_size = 256 * 2048,
+ .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 = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 256 * 2048,
+ .nsectors = 16,
+ .sector_size = 32768,
+ .page_size = 256,
+ },
+/* .bank[1] = { */
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+ {
+ .chipid_cidr = 0x289B0A60,
+ .name = "at91sam3s8b",
+ .total_flash_size = 256 * 2048,
+ .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 = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 256 * 2048,
+ .nsectors = 16,
+ .sector_size = 32768,
+ .page_size = 256,
+ },
+/* .bank[1] = { */
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+ {
+ .chipid_cidr = 0x28AB0A60,
+ .name = "at91sam3s8c",
+ .total_flash_size = 256 * 2048,
+ .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 = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 256 * 2048,
+ .nsectors = 16,
+ .sector_size = 32768,
+ .page_size = 256,
+ },
+/* .bank[1] = { */
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
/* Start at91sam3n* series */
{
},
},
+ {
+ .chipid_cidr = 0x29480360,
+ .name = "at91sam3n0b",
+ .total_flash_size = 32 * 1024,
+ .total_sram_size = 8 * 1024,
+ .n_gpnvms = 3,
+ .n_banks = 1,
+
+/* .bank[0] = { */
+ {
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_N,
+ .controller_address = 0x400e0A00,
+ .flash_wait_states = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 32 * 1024,
+ .nsectors = 2,
+ .sector_size = 16384,
+ .page_size = 256,
+ },
+
+/* .bank[1] = { */
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+ },
+ },
+ },
+
+ {
+ .chipid_cidr = 0x29380360,
+ .name = "at91sam3n0a",
+ .total_flash_size = 32 * 1024,
+ .total_sram_size = 8 * 1024,
+ .n_gpnvms = 3,
+ .n_banks = 1,
+
+/* .bank[0] = { */
+ {
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_N,
+ .controller_address = 0x400e0A00,
+ .flash_wait_states = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 32 * 1024,
+ .nsectors = 2,
+ .sector_size = 16384,
+ .page_size = 256,
+ },
+
+/* .bank[1] = { */
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+ },
+ },
+ },
+
+ {
+ .chipid_cidr = 0x29450260,
+ .name = "at91sam3n00b",
+ .total_flash_size = 16 * 1024,
+ .total_sram_size = 4 * 1024,
+ .n_gpnvms = 3,
+ .n_banks = 1,
+
+/* .bank[0] = { */
+ {
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_N,
+ .controller_address = 0x400e0A00,
+ .flash_wait_states = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 16 * 1024,
+ .nsectors = 1,
+ .sector_size = 16384,
+ .page_size = 256,
+ },
+
+/* .bank[1] = { */
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+ },
+ },
+ },
+
+ {
+ .chipid_cidr = 0x29350260,
+ .name = "at91sam3n00a",
+ .total_flash_size = 16 * 1024,
+ .total_sram_size = 4 * 1024,
+ .n_gpnvms = 3,
+ .n_banks = 1,
+
+/* .bank[0] = { */
+ {
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_N,
+ .controller_address = 0x400e0A00,
+ .flash_wait_states = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 16 * 1024,
+ .nsectors = 1,
+ .sector_size = 16384,
+ .page_size = 256,
+ },
+
+/* .bank[1] = { */
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+ },
+ },
+ },
+
+
+ /* Start at91sam3a series*/
+ /* System boots at address 0x0 */
+ /* gpnvm[1] = selects boot code */
+ /* if gpnvm[1] == 0 */
+ /* boot is via "SAMBA" (rom) */
+ /* else */
+ /* boot is via FLASH */
+ /* Selection is via gpnvm[2] */
+ /* endif */
+ /* */
+ /* NOTE: banks 0 & 1 switch places */
+ /* if gpnvm[2] == 0 */
+ /* Bank0 is the boot rom */
+ /* else */
+ /* Bank1 is the boot rom */
+ /* endif */
+
+ {
+ .chipid_cidr = 0x283E0A60,
+ .name = "at91sam3a8c",
+ .total_flash_size = 512 * 1024,
+ .total_sram_size = 96 * 1024,
+ .n_gpnvms = 3,
+ .n_banks = 2,
+ {
+/* .bank[0] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK0_BASE_AX,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 256 * 1024,
+ .nsectors = 16,
+ .sector_size = 16384,
+ .page_size = 256,
+ },
+/* .bank[1] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 1,
+ .base_address = FLASH_BANK1_BASE_512K_AX,
+ .controller_address = 0x400e0c00,
+ .flash_wait_states = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 256 * 1024,
+ .nsectors = 16,
+ .sector_size = 16384,
+ .page_size = 256,
+
+ },
+ },
+ },
+ {
+ .chipid_cidr = 0x283B0960,
+ .name = "at91sam3a4c",
+ .total_flash_size = 256 * 1024,
+ .total_sram_size = 64 * 1024,
+ .n_gpnvms = 3,
+ .n_banks = 2,
+ {
+/* .bank[0] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK0_BASE_AX,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 128 * 1024,
+ .nsectors = 8,
+ .sector_size = 16384,
+ .page_size = 256,
+ },
+/* .bank[1] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 1,
+ .base_address = FLASH_BANK1_BASE_256K_AX,
+ .controller_address = 0x400e0c00,
+ .flash_wait_states = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 128 * 1024,
+ .nsectors = 8,
+ .sector_size = 16384,
+ .page_size = 256,
+
+ },
+ },
+ },
+
+ /* Start at91sam3x* series */
+ /* System boots at address 0x0 */
+ /* gpnvm[1] = selects boot code */
+ /* if gpnvm[1] == 0 */
+ /* boot is via "SAMBA" (rom) */
+ /* else */
+ /* boot is via FLASH */
+ /* Selection is via gpnvm[2] */
+ /* endif */
+ /* */
+ /* NOTE: banks 0 & 1 switch places */
+ /* if gpnvm[2] == 0 */
+ /* Bank0 is the boot rom */
+ /* else */
+ /* Bank1 is the boot rom */
+ /* endif */
+ /*at91sam3x8h - ES has an incorrect CIDR of 0x286E0A20*/
+ {
+ .chipid_cidr = 0x286E0A20,
+ .name = "at91sam3x8h - ES",
+ .total_flash_size = 512 * 1024,
+ .total_sram_size = 96 * 1024,
+ .n_gpnvms = 3,
+ .n_banks = 2,
+ {
+/* .bank[0] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK0_BASE_AX,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 256 * 1024,
+ .nsectors = 16,
+ .sector_size = 16384,
+ .page_size = 256,
+ },
+/* .bank[1] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 1,
+ .base_address = FLASH_BANK1_BASE_512K_AX,
+ .controller_address = 0x400e0c00,
+ .flash_wait_states = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 256 * 1024,
+ .nsectors = 16,
+ .sector_size = 16384,
+ .page_size = 256,
+
+ },
+ },
+ },
+ /*at91sam3x8h - ES2 and up uses the correct CIDR of 0x286E0A60*/
+ {
+ .chipid_cidr = 0x286E0A60,
+ .name = "at91sam3x8h",
+ .total_flash_size = 512 * 1024,
+ .total_sram_size = 96 * 1024,
+ .n_gpnvms = 3,
+ .n_banks = 2,
+ {
+/* .bank[0] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK0_BASE_AX,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 256 * 1024,
+ .nsectors = 16,
+ .sector_size = 16384,
+ .page_size = 256,
+ },
+/* .bank[1] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 1,
+ .base_address = FLASH_BANK1_BASE_512K_AX,
+ .controller_address = 0x400e0c00,
+ .flash_wait_states = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 256 * 1024,
+ .nsectors = 16,
+ .sector_size = 16384,
+ .page_size = 256,
+
+ },
+ },
+ },
+ {
+ .chipid_cidr = 0x285E0A60,
+ .name = "at91sam3x8e",
+ .total_flash_size = 512 * 1024,
+ .total_sram_size = 96 * 1024,
+ .n_gpnvms = 3,
+ .n_banks = 2,
+ {
+/* .bank[0] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK0_BASE_AX,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 256 * 1024,
+ .nsectors = 16,
+ .sector_size = 16384,
+ .page_size = 256,
+ },
+/* .bank[1] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 1,
+ .base_address = FLASH_BANK1_BASE_512K_AX,
+ .controller_address = 0x400e0c00,
+ .flash_wait_states = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 256 * 1024,
+ .nsectors = 16,
+ .sector_size = 16384,
+ .page_size = 256,
+
+ },
+ },
+ },
+ {
+ .chipid_cidr = 0x284E0A60,
+ .name = "at91sam3x8c",
+ .total_flash_size = 512 * 1024,
+ .total_sram_size = 96 * 1024,
+ .n_gpnvms = 3,
+ .n_banks = 2,
+ {
+/* .bank[0] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK0_BASE_AX,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 256 * 1024,
+ .nsectors = 16,
+ .sector_size = 16384,
+ .page_size = 256,
+ },
+/* .bank[1] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 1,
+ .base_address = FLASH_BANK1_BASE_512K_AX ,
+ .controller_address = 0x400e0c00,
+ .flash_wait_states = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 256 * 1024,
+ .nsectors = 16,
+ .sector_size = 16384,
+ .page_size = 256,
+
+ },
+ },
+ },
+ {
+ .chipid_cidr = 0x285B0960,
+ .name = "at91sam3x4e",
+ .total_flash_size = 256 * 1024,
+ .total_sram_size = 64 * 1024,
+ .n_gpnvms = 3,
+ .n_banks = 2,
+ {
+/* .bank[0] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK0_BASE_AX,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 128 * 1024,
+ .nsectors = 8,
+ .sector_size = 16384,
+ .page_size = 256,
+ },
+/* .bank[1] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 1,
+ .base_address = FLASH_BANK1_BASE_256K_AX,
+ .controller_address = 0x400e0c00,
+ .flash_wait_states = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 128 * 1024,
+ .nsectors = 8,
+ .sector_size = 16384,
+ .page_size = 256,
+
+ },
+ },
+ },
+ {
+ .chipid_cidr = 0x284B0960,
+ .name = "at91sam3x4c",
+ .total_flash_size = 256 * 1024,
+ .total_sram_size = 64 * 1024,
+ .n_gpnvms = 3,
+ .n_banks = 2,
+ {
+/* .bank[0] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK0_BASE_AX,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 128 * 1024,
+ .nsectors = 8,
+ .sector_size = 16384,
+ .page_size = 256,
+ },
+/* .bank[1] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 1,
+ .base_address = FLASH_BANK1_BASE_256K_AX,
+ .controller_address = 0x400e0c00,
+ .flash_wait_states = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 128 * 1024,
+ .nsectors = 8,
+ .sector_size = 16384,
+ .page_size = 256,
+
+ },
+ },
+ },
/* terminate */
{
.chipid_cidr = 0,
}
/* show the basics */
- LOG_USER_N("\t%*s: %*d [0x%0*x] ",
+ LOG_USER_N("\t%*s: %*" PRIu32 " [0x%0*" PRIx32 "] ",
REG_NAME_WIDTH, regname,
dwidth, v,
hwidth, v);
v = (v * pChip->cfg.slow_freq) / 16;
pChip->cfg.mainosc_freq = v;
- LOG_USER("(%3.03f Mhz (%d.%03dkhz slowclk)",
+ LOG_USER("(%3.03f Mhz (%" PRIu32 ".%03" PRIu32 "khz slowclk)",
_tomhz(v),
- pChip->cfg.slow_freq / 1000,
- pChip->cfg.slow_freq % 1000);
+ (uint32_t)(pChip->cfg.slow_freq / 1000),
+ (uint32_t)(pChip->cfg.slow_freq % 1000));
}
static void sam3_explain_ckgr_plla(struct sam3_chip *pChip)
LOG_USER("\tPLLA Freq: (Disabled,mula = 0)");
else if (diva == 0)
LOG_USER("\tPLLA Freq: (Disabled,diva = 0)");
- else if (diva == 1) {
- pChip->cfg.plla_freq = (pChip->cfg.mainosc_freq * (mula + 1));
+ else if (diva >= 1) {
+ pChip->cfg.plla_freq = (pChip->cfg.mainosc_freq * (mula + 1) / diva);
LOG_USER("\tPLLA Freq: %3.03f MHz",
_tomhz(pChip->cfg.plla_freq));
}
SAM3_ENTRY(PMC_SCSR, NULL),
SAM3_ENTRY(PMC_SR, NULL),
SAM3_ENTRY(CHIPID_CIDR, sam3_explain_chipid_cidr),
+ SAM3_ENTRY(CHIPID_CIDR2, sam3_explain_chipid_cidr),
SAM3_ENTRY(CHIPID_EXID, NULL),
- SAM3_ENTRY(SUPC_CR, NULL),
-
+ SAM3_ENTRY(CHIPID_EXID2, NULL),
/* TERMINATE THE LIST */
{ .name = NULL }
};
static struct sam3_bank_private *get_sam3_bank_private(struct flash_bank *bank)
{
- return (struct sam3_bank_private *)(bank->driver_priv);
+ return bank->driver_priv;
}
/**
r = sam3_ReadThisReg(pChip,
sam3_get_reg_ptr(&(pChip->cfg), pReg));
if (r != ERROR_OK) {
- LOG_ERROR("Cannot read SAM3 registere: %s @ 0x%08x, Error: %d",
+ LOG_ERROR("Cannot read SAM3 register: %s @ 0x%08x, Error: %d",
pReg->name, ((unsigned)(pReg->address)), r);
return r;
}
-
pReg++;
}
+ /* Chip identification register
+ *
+ * Unfortunately, the chip identification register is not at
+ * a constant address across all of the SAM3 series'. As a
+ * consequence, a simple heuristic is used to find where it's
+ * at...
+ *
+ * If the contents at the first address is zero, then we know
+ * that the second address is where the chip id register is.
+ * We can deduce this because for those SAM's that have the
+ * chip id @ 0x400e0940, the first address, 0x400e0740, is
+ * located in the memory map of the Power Management Controller
+ * (PMC). Furthermore, the address is not used by the PMC.
+ * So when read, the memory controller returns zero.*/
+ if (pChip->cfg.CHIPID_CIDR == 0) {
+ /*Put the correct CIDR and EXID values in the pChip structure */
+ pChip->cfg.CHIPID_CIDR = pChip->cfg.CHIPID_CIDR2;
+ pChip->cfg.CHIPID_EXID = pChip->cfg.CHIPID_EXID2;
+ }
return ERROR_OK;
}
/* display all regs */
LOG_DEBUG("Start: %s", pReg->name);
regval = *sam3_get_reg_ptr(&(pChip->cfg), pReg);
- LOG_USER("%*s: [0x%08x] -> 0x%08x",
+ LOG_USER("%*s: [0x%08" PRIx32 "] -> 0x%08" PRIx32,
REG_NAME_WIDTH,
pReg->name,
pReg->address,
LOG_USER(" cpu-freq: %3.03f MHz", _tomhz(pChip->cfg.cpu_freq));
LOG_USER("mclk-freq: %3.03f MHz", _tomhz(pChip->cfg.mclk_freq));
- LOG_USER(" UniqueId: 0x%08x 0x%08x 0x%08x 0x%08x",
+ LOG_USER(" UniqueId: 0x%08" PRIx32 " 0x%08" PRIx32 " 0x%08" PRIx32 " 0x%08" PRIx32,
pChip->cfg.unique_id[0],
pChip->cfg.unique_id[1],
pChip->cfg.unique_id[2],
default:
LOG_ERROR("Address 0x%08x invalid bank address (try 0x%08x or 0x%08x "
"[at91sam3u series] or 0x%08x [at91sam3s series] or "
- "0x%08x [at91sam3n series])",
+ "0x%08x [at91sam3n series] or 0x%08x or 0x%08x or 0x%08x[at91sam3ax series] )",
((unsigned int)(bank->base)),
((unsigned int)(FLASH_BANK0_BASE_U)),
((unsigned int)(FLASH_BANK1_BASE_U)),
((unsigned int)(FLASH_BANK_BASE_S)),
- ((unsigned int)(FLASH_BANK_BASE_N)));
+ ((unsigned int)(FLASH_BANK_BASE_N)),
+ ((unsigned int)(FLASH_BANK0_BASE_AX)),
+ ((unsigned int)(FLASH_BANK1_BASE_256K_AX)),
+ ((unsigned int)(FLASH_BANK1_BASE_512K_AX)));
return ERROR_FAIL;
break;
- /* at91sam3u series */
+ /* at91sam3s and at91sam3n series only has bank 0*/
+ /* at91sam3u and at91sam3ax series has the same address for bank 0*/
+ case FLASH_BANK_BASE_S:
case FLASH_BANK0_BASE_U:
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 at91sam3u or at91sam3ax series */
case FLASH_BANK1_BASE_U:
+ case FLASH_BANK1_BASE_256K_AX:
+ case FLASH_BANK1_BASE_512K_AX:
bank->driver_priv = &(pChip->details.bank[1]);
bank->bank_number = 1;
pChip->details.bank[1].pChip = pChip;
pChip->details.bank[1].pBank = bank;
break;
-
- /* at91sam3s and at91sam3n series */
- case FLASH_BANK_BASE_S:
- bank->driver_priv = &(pChip->details.bank[0]);
- bank->bank_number = 0;
- pChip->details.bank[0].pChip = pChip;
- pChip->details.bank[0].pBank = bank;
- break;
}
/* we initialize after probing. */
pDetails = all_sam3_details;
while (pDetails->name) {
/* Compare cidr without version bits */
- if (pDetails->chipid_cidr == (pPrivate->pChip->cfg.CHIPID_CIDR & 0xFFFFFFE0))
+ if (((pDetails->chipid_cidr ^ pPrivate->pChip->cfg.CHIPID_CIDR) & 0xFFFFFFE0) == 0)
break;
else
pDetails++;
}
if (pDetails->name == NULL) {
- LOG_ERROR("SAM3 ChipID 0x%08x not found in table (perhaps you can this chip?)",
+ LOG_ERROR("SAM3 ChipID 0x%08x not found in table (perhaps you can ID this chip?)",
(unsigned int)(pPrivate->pChip->cfg.CHIPID_CIDR));
/* Help the victim, print details about the chip */
- LOG_INFO("SAM3 CHIPID_CIDR: 0x%08x decodes as follows",
+ LOG_INFO("SAM3 CHIPID_CIDR: 0x%08" PRIx32 " decodes as follows",
pPrivate->pChip->cfg.CHIPID_CIDR);
sam3_explain_chipid_cidr(pPrivate->pChip);
return ERROR_FAIL;
LOG_DEBUG("Here");
return FLASHD_EraseEntireBank(pPrivate);
}
- LOG_INFO("sam3 auto-erases while programing (request ignored)");
+ LOG_INFO("sam3 auto-erases while programming (request ignored)");
return ERROR_OK;
}
}
-static int sam3_info(struct flash_bank *bank, char *buf, int buf_size)
-{
- if (bank->target->state != TARGET_HALTED) {
- LOG_ERROR("Target not halted");
- return ERROR_TARGET_NOT_HALTED;
- }
- buf[0] = 0;
- return ERROR_OK;
-}
-
static int sam3_page_read(struct sam3_bank_private *pPrivate, unsigned pagenum, uint8_t *buf)
{
uint32_t adr;
int r;
adr = pagenum * pPrivate->page_size;
- adr += adr + pPrivate->base_address;
+ adr += pPrivate->base_address;
r = target_read_memory(pPrivate->pChip->target,
adr,
return r;
}
-/* The code below is basically this: */
-/* compiled with */
-/* arm-none-eabi-gcc -mthumb -mcpu = cortex-m3 -O9 -S ./foobar.c -o foobar.s */
-/* */
-/* Only the *CPU* can write to the flash buffer. */
-/* the DAP cannot... so - we download this 28byte thing */
-/* Run the algorithm - (below) */
-/* to program the device */
-/* */
-/* ======================================== */
-/* #include <stdint.h> */
-/* */
-/* struct foo { */
-/* uint32_t *dst; */
-/* const uint32_t *src; */
-/* int n; */
-/* volatile uint32_t *base; */
-/* uint32_t cmd; */
-/* }; */
-/* */
-/* */
-/* uint32_t sam3_function(struct foo *p) */
-/* { */
-/* volatile uint32_t *v; */
-/* uint32_t *d; */
-/* const uint32_t *s; */
-/* int n; */
-/* uint32_t r; */
-/* */
-/* d = p->dst; */
-/* s = p->src; */
-/* n = p->n; */
-/* */
-/* do { */
-/* *d++ = *s++; */
-/* } while (--n) */
-/* ; */
-/* */
-/* v = p->base; */
-/* */
-/* v[ 1 ] = p->cmd; */
-/* do { */
-/* r = v[8/4]; */
-/* } while (!(r&1)) */
-/* ; */
-/* return r; */
-/* } */
-/* ======================================== */
-
-static const uint8_t
- sam3_page_write_opcodes[] = {
- /* 24 0000 0446 mov r4, r0 */
- 0x04, 0x46,
- /* 25 0002 6168 ldr r1, [r4, #4] */
- 0x61, 0x68,
- /* 26 0004 0068 ldr r0, [r0, #0] */
- 0x00, 0x68,
- /* 27 0006 A268 ldr r2, [r4, #8] */
- 0xa2, 0x68,
- /* 28 @ lr needed for prologue */
- /* 29 .L2: */
- /* 30 0008 51F8043B ldr r3, [r1], #4 */
- 0x51, 0xf8, 0x04, 0x3b,
- /* 31 000c 12F1FF32 adds r2, r2, #-1 */
- 0x12, 0xf1, 0xff, 0x32,
- /* 32 0010 40F8043B str r3, [r0], #4 */
- 0x40, 0xf8, 0x04, 0x3b,
- /* 33 0014 F8D1 bne .L2 */
- 0xf8, 0xd1,
- /* 34 0016 E268 ldr r2, [r4, #12] */
- 0xe2, 0x68,
- /* 35 0018 2369 ldr r3, [r4, #16] */
- 0x23, 0x69,
- /* 36 001a 5360 str r3, [r2, #4] */
- 0x53, 0x60,
- /* 37 001c 0832 adds r2, r2, #8 */
- 0x08, 0x32,
- /* 38 .L4: */
- /* 39 001e 1068 ldr r0, [r2, #0] */
- 0x10, 0x68,
- /* 40 0020 10F0010F tst r0, #1 */
- 0x10, 0xf0, 0x01, 0x0f,
- /* 41 0024 FBD0 beq .L4 */
- 0xfb, 0xd0,
- 0x00, 0xBE /* bkpt #0 */
-};
-
-static int sam3_page_write(struct sam3_bank_private *pPrivate, unsigned pagenum, uint8_t *buf)
+static int sam3_page_write(struct sam3_bank_private *pPrivate, unsigned pagenum, const uint8_t *buf)
{
uint32_t adr;
uint32_t status;
int r;
adr = pagenum * pPrivate->page_size;
- adr += (adr + pPrivate->base_address);
+ adr += pPrivate->base_address;
/* Get flash mode register value */
r = target_read_u32(pPrivate->pChip->target, pPrivate->controller_address, &fmr);
}
static int sam3_write(struct flash_bank *bank,
- uint8_t *buffer,
+ const uint8_t *buffer,
uint32_t offset,
uint32_t count)
{
r = sam3_page_write(pPrivate, page_cur, pagebuffer);
if (r != ERROR_OK)
goto done;
- buffer += count;
}
LOG_DEBUG("Done!");
r = ERROR_OK;
.auto_probe = sam3_auto_probe,
.erase_check = sam3_erase_check,
.protect_check = sam3_protect_check,
- .info = sam3_info,
};