flash/nor/at91sam4: ATSAMG55x19 Rev.B
[openocd.git] / src / flash / nor / at91sam4.c
1 /***************************************************************************
2 * Copyright (C) 2009 by Duane Ellis *
3 * openocd@duaneellis.com *
4 * *
5 * Copyright (C) 2010 by Olaf Lüke (at91sam3s* support) *
6 * olaf@uni-paderborn.de *
7 * *
8 * Copyright (C) 2011 by Olivier Schonken, Jim Norris *
9 * (at91sam3x* & at91sam4 support)* *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
20 * *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
23 ****************************************************************************/
24
25 /* Some of the lower level code was based on code supplied by
26 * ATMEL under this copyright. */
27
28 /* BEGIN ATMEL COPYRIGHT */
29 /* ----------------------------------------------------------------------------
30 * ATMEL Microcontroller Software Support
31 * ----------------------------------------------------------------------------
32 * Copyright (c) 2009, Atmel Corporation
33 *
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions are met:
38 *
39 * - Redistributions of source code must retain the above copyright notice,
40 * this list of conditions and the disclaimer below.
41 *
42 * Atmel's name may not be used to endorse or promote products derived from
43 * this software without specific prior written permission.
44 *
45 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
46 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
47 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
48 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
49 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
50 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
51 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
52 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
53 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
54 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
55 * ----------------------------------------------------------------------------
56 */
57 /* END ATMEL COPYRIGHT */
58
59 #ifdef HAVE_CONFIG_H
60 #include "config.h"
61 #endif
62
63 #include "imp.h"
64 #include <helper/time_support.h>
65
66 #define REG_NAME_WIDTH (12)
67
68 /* at91sam4s/at91sam4e/at91sam4c series (has always one flash bank)*/
69 #define FLASH_BANK_BASE_S 0x00400000
70 #define FLASH_BANK_BASE_C 0x01000000
71
72 /* at91sam4sd series (two one flash banks), first bank address */
73 #define FLASH_BANK0_BASE_SD FLASH_BANK_BASE_S
74 /* at91sam4sd16x, second bank address */
75 #define FLASH_BANK1_BASE_1024K_SD (FLASH_BANK0_BASE_SD+(1024*1024/2))
76 /* at91sam4sd32x, second bank address */
77 #define FLASH_BANK1_BASE_2048K_SD (FLASH_BANK0_BASE_SD+(2048*1024/2))
78
79 /* at91sam4c32x, first and second bank address */
80 #define FLASH_BANK0_BASE_C32 FLASH_BANK_BASE_C
81 #define FLASH_BANK1_BASE_C32 (FLASH_BANK_BASE_C+(2048*1024/2))
82
83 #define AT91C_EFC_FCMD_GETD (0x0) /* (EFC) Get Flash Descriptor */
84 #define AT91C_EFC_FCMD_WP (0x1) /* (EFC) Write Page */
85 #define AT91C_EFC_FCMD_WPL (0x2) /* (EFC) Write Page and Lock */
86 #define AT91C_EFC_FCMD_EWP (0x3) /* (EFC) Erase Page and Write Page */
87 #define AT91C_EFC_FCMD_EWPL (0x4) /* (EFC) Erase Page and Write Page then Lock */
88 #define AT91C_EFC_FCMD_EA (0x5) /* (EFC) Erase All */
89 /* cmd6 is not present in the at91sam4u4/2/1 data sheet table 19-2 */
90 /* #define AT91C_EFC_FCMD_EPL (0x6) // (EFC) Erase plane? */
91 #define AT91C_EFC_FCMD_EPA (0x7) /* (EFC) Erase pages */
92 #define AT91C_EFC_FCMD_SLB (0x8) /* (EFC) Set Lock Bit */
93 #define AT91C_EFC_FCMD_CLB (0x9) /* (EFC) Clear Lock Bit */
94 #define AT91C_EFC_FCMD_GLB (0xA) /* (EFC) Get Lock Bit */
95 #define AT91C_EFC_FCMD_SFB (0xB) /* (EFC) Set Fuse Bit */
96 #define AT91C_EFC_FCMD_CFB (0xC) /* (EFC) Clear Fuse Bit */
97 #define AT91C_EFC_FCMD_GFB (0xD) /* (EFC) Get Fuse Bit */
98 #define AT91C_EFC_FCMD_STUI (0xE) /* (EFC) Start Read Unique ID */
99 #define AT91C_EFC_FCMD_SPUI (0xF) /* (EFC) Stop Read Unique ID */
100
101 #define offset_EFC_FMR 0
102 #define offset_EFC_FCR 4
103 #define offset_EFC_FSR 8
104 #define offset_EFC_FRR 12
105
106 extern const struct flash_driver at91sam4_flash;
107
108 static float _tomhz(uint32_t freq_hz)
109 {
110 float f;
111
112 f = ((float)(freq_hz)) / 1000000.0;
113 return f;
114 }
115
116 /* How the chip is configured. */
117 struct sam4_cfg {
118 uint32_t unique_id[4];
119
120 uint32_t slow_freq;
121 uint32_t rc_freq;
122 uint32_t mainosc_freq;
123 uint32_t plla_freq;
124 uint32_t mclk_freq;
125 uint32_t cpu_freq;
126 uint32_t fclk_freq;
127 uint32_t pclk0_freq;
128 uint32_t pclk1_freq;
129 uint32_t pclk2_freq;
130
131
132 #define SAM4_CHIPID_CIDR (0x400E0740)
133 uint32_t CHIPID_CIDR;
134 #define SAM4_CHIPID_EXID (0x400E0744)
135 uint32_t CHIPID_EXID;
136
137 #define SAM4_PMC_BASE (0x400E0400)
138 #define SAM4_PMC_SCSR (SAM4_PMC_BASE + 0x0008)
139 uint32_t PMC_SCSR;
140 #define SAM4_PMC_PCSR (SAM4_PMC_BASE + 0x0018)
141 uint32_t PMC_PCSR;
142 #define SAM4_CKGR_UCKR (SAM4_PMC_BASE + 0x001c)
143 uint32_t CKGR_UCKR;
144 #define SAM4_CKGR_MOR (SAM4_PMC_BASE + 0x0020)
145 uint32_t CKGR_MOR;
146 #define SAM4_CKGR_MCFR (SAM4_PMC_BASE + 0x0024)
147 uint32_t CKGR_MCFR;
148 #define SAM4_CKGR_PLLAR (SAM4_PMC_BASE + 0x0028)
149 uint32_t CKGR_PLLAR;
150 #define SAM4_PMC_MCKR (SAM4_PMC_BASE + 0x0030)
151 uint32_t PMC_MCKR;
152 #define SAM4_PMC_PCK0 (SAM4_PMC_BASE + 0x0040)
153 uint32_t PMC_PCK0;
154 #define SAM4_PMC_PCK1 (SAM4_PMC_BASE + 0x0044)
155 uint32_t PMC_PCK1;
156 #define SAM4_PMC_PCK2 (SAM4_PMC_BASE + 0x0048)
157 uint32_t PMC_PCK2;
158 #define SAM4_PMC_SR (SAM4_PMC_BASE + 0x0068)
159 uint32_t PMC_SR;
160 #define SAM4_PMC_IMR (SAM4_PMC_BASE + 0x006c)
161 uint32_t PMC_IMR;
162 #define SAM4_PMC_FSMR (SAM4_PMC_BASE + 0x0070)
163 uint32_t PMC_FSMR;
164 #define SAM4_PMC_FSPR (SAM4_PMC_BASE + 0x0074)
165 uint32_t PMC_FSPR;
166 };
167
168 struct sam4_bank_private {
169 bool probed;
170 /* DANGER: THERE ARE DRAGONS HERE.. */
171 /* NOTE: If you add more 'ghost' pointers */
172 /* be aware that you must *manually* update */
173 /* these pointers in the function sam4_GetDetails() */
174 /* See the comment "Here there be dragons" */
175
176 /* so we can find the chip we belong to */
177 struct sam4_chip *pChip;
178 /* so we can find the original bank pointer */
179 struct flash_bank *pBank;
180 unsigned bank_number;
181 uint32_t controller_address;
182 uint32_t base_address;
183 uint32_t flash_wait_states;
184 bool present;
185 unsigned size_bytes;
186 unsigned nsectors;
187 unsigned sector_size;
188 unsigned page_size;
189 };
190
191 struct sam4_chip_details {
192 /* THERE ARE DRAGONS HERE.. */
193 /* note: If you add pointers here */
194 /* be careful about them as they */
195 /* may need to be updated inside */
196 /* the function: "sam4_GetDetails() */
197 /* which copy/overwrites the */
198 /* 'runtime' copy of this structure */
199 uint32_t chipid_cidr;
200 const char *name;
201
202 unsigned n_gpnvms;
203 #define SAM4_N_NVM_BITS 3
204 unsigned gpnvm[SAM4_N_NVM_BITS];
205 unsigned total_flash_size;
206 unsigned total_sram_size;
207 unsigned n_banks;
208 #define SAM4_MAX_FLASH_BANKS 2
209 /* these are "initialized" from the global const data */
210 struct sam4_bank_private bank[SAM4_MAX_FLASH_BANKS];
211 };
212
213 struct sam4_chip {
214 struct sam4_chip *next;
215 bool probed;
216
217 /* this is "initialized" from the global const structure */
218 struct sam4_chip_details details;
219 struct target *target;
220 struct sam4_cfg cfg;
221 };
222
223
224 struct sam4_reg_list {
225 uint32_t address; size_t struct_offset; const char *name;
226 void (*explain_func)(struct sam4_chip *pInfo);
227 };
228
229 static struct sam4_chip *all_sam4_chips;
230
231 static struct sam4_chip *get_current_sam4(struct command_invocation *cmd)
232 {
233 struct target *t;
234 static struct sam4_chip *p;
235
236 t = get_current_target(cmd->ctx);
237 if (!t) {
238 command_print(cmd, "No current target?");
239 return NULL;
240 }
241
242 p = all_sam4_chips;
243 if (!p) {
244 /* this should not happen */
245 /* the command is not registered until the chip is created? */
246 command_print(cmd, "No SAM4 chips exist?");
247 return NULL;
248 }
249
250 while (p) {
251 if (p->target == t)
252 return p;
253 p = p->next;
254 }
255 command_print(cmd, "Cannot find SAM4 chip?");
256 return NULL;
257 }
258
259 /*The actual sector size of the SAM4S flash memory is 65536 bytes. 16 sectors for a 1024KB device*/
260 /*The lockregions are 8KB per lock region, with a 1024KB device having 128 lock regions. */
261 /*For the best results, nsectors are thus set to the amount of lock regions, and the sector_size*/
262 /*set to the lock region size. Page erases are used to erase 8KB sections when programming*/
263
264 /* these are used to *initialize* the "pChip->details" structure. */
265 static const struct sam4_chip_details all_sam4_details[] = {
266 /* Start at91sam4c* series */
267 /* at91sam4c32e - LQFP144 */
268 {
269 .chipid_cidr = 0xA66D0EE0,
270 .name = "at91sam4c32e",
271 .total_flash_size = 2024 * 1024,
272 .total_sram_size = 256 * 1024,
273 .n_gpnvms = 3,
274 .n_banks = 2,
275 /* .bank[0] = { */
276 {
277 {
278 .probed = false,
279 .pChip = NULL,
280 .pBank = NULL,
281 .bank_number = 0,
282 .base_address = FLASH_BANK0_BASE_C32,
283 .controller_address = 0x400e0a00,
284 .flash_wait_states = 5,
285 .present = true,
286 .size_bytes = 1024 * 1024,
287 .nsectors = 128,
288 .sector_size = 8192,
289 .page_size = 512,
290 },
291 /* .bank[1] = { */
292 {
293 .probed = false,
294 .pChip = NULL,
295 .pBank = NULL,
296 .bank_number = 1,
297 .base_address = FLASH_BANK1_BASE_C32,
298 .controller_address = 0x400e0c00,
299 .flash_wait_states = 5,
300 .present = true,
301 .size_bytes = 1024 * 1024,
302 .nsectors = 128,
303 .sector_size = 8192,
304 .page_size = 512,
305 },
306 },
307 },
308 /* at91sam4c32c - LQFP100 */
309 {
310 .chipid_cidr = 0xA64D0EE0,
311 .name = "at91sam4c32c",
312 .total_flash_size = 2024 * 1024,
313 .total_sram_size = 256 * 1024,
314 .n_gpnvms = 3,
315 .n_banks = 2,
316 /* .bank[0] = { */
317 {
318 {
319 .probed = false,
320 .pChip = NULL,
321 .pBank = NULL,
322 .bank_number = 0,
323 .base_address = FLASH_BANK0_BASE_C32,
324 .controller_address = 0x400e0a00,
325 .flash_wait_states = 5,
326 .present = true,
327 .size_bytes = 1024 * 1024,
328 .nsectors = 128,
329 .sector_size = 8192,
330 .page_size = 512,
331 },
332 /* .bank[1] = { */
333 {
334 .probed = false,
335 .pChip = NULL,
336 .pBank = NULL,
337 .bank_number = 1,
338 .base_address = FLASH_BANK1_BASE_C32,
339 .controller_address = 0x400e0c00,
340 .flash_wait_states = 5,
341 .present = true,
342 .size_bytes = 1024 * 1024,
343 .nsectors = 128,
344 .sector_size = 8192,
345 .page_size = 512,
346 },
347 },
348 },
349 /* at91sam4c16c - LQFP100 */
350 {
351 .chipid_cidr = 0xA64C0CE0,
352 .name = "at91sam4c16c",
353 .total_flash_size = 1024 * 1024,
354 .total_sram_size = 128 * 1024,
355 .n_gpnvms = 2,
356 .n_banks = 1,
357 {
358 /* .bank[0] = {*/
359 {
360 .probed = false,
361 .pChip = NULL,
362 .pBank = NULL,
363 .bank_number = 0,
364 .base_address = FLASH_BANK_BASE_C,
365 .controller_address = 0x400e0a00,
366 .flash_wait_states = 5,
367 .present = true,
368 .size_bytes = 1024 * 1024,
369 .nsectors = 128,
370 .sector_size = 8192,
371 .page_size = 512,
372 },
373 /* .bank[1] = {*/
374 {
375 .present = false,
376 .probed = false,
377 .bank_number = 1,
378
379 },
380 },
381 },
382 /* at91sam4c8c - LQFP100 */
383 {
384 .chipid_cidr = 0xA64C0AE0,
385 .name = "at91sam4c8c",
386 .total_flash_size = 512 * 1024,
387 .total_sram_size = 128 * 1024,
388 .n_gpnvms = 2,
389 .n_banks = 1,
390 {
391 /* .bank[0] = {*/
392 {
393 .probed = false,
394 .pChip = NULL,
395 .pBank = NULL,
396 .bank_number = 0,
397 .base_address = FLASH_BANK_BASE_C,
398 .controller_address = 0x400e0a00,
399 .flash_wait_states = 5,
400 .present = true,
401 .size_bytes = 512 * 1024,
402 .nsectors = 64,
403 .sector_size = 8192,
404 .page_size = 512,
405 },
406 /* .bank[1] = {*/
407 {
408 .present = false,
409 .probed = false,
410 .bank_number = 1,
411
412 },
413 },
414 },
415 /* at91sam4c4c (rev B) - LQFP100 */
416 {
417 .chipid_cidr = 0xA64C0CE5,
418 .name = "at91sam4c4c",
419 .total_flash_size = 256 * 1024,
420 .total_sram_size = 128 * 1024,
421 .n_gpnvms = 2,
422 .n_banks = 1,
423 {
424 /* .bank[0] = {*/
425 {
426 .probed = false,
427 .pChip = NULL,
428 .pBank = NULL,
429 .bank_number = 0,
430 .base_address = FLASH_BANK_BASE_C,
431 .controller_address = 0x400e0a00,
432 .flash_wait_states = 5,
433 .present = true,
434 .size_bytes = 256 * 1024,
435 .nsectors = 32,
436 .sector_size = 8192,
437 .page_size = 512,
438 },
439 /* .bank[1] = {*/
440 {
441 .present = false,
442 .probed = false,
443 .bank_number = 1,
444
445 },
446 },
447 },
448
449 /* Start at91sam4e* series */
450 /*atsam4e16e - LQFP144/LFBGA144*/
451 {
452 .chipid_cidr = 0xA3CC0CE0,
453 .name = "at91sam4e16e",
454 .total_flash_size = 1024 * 1024,
455 .total_sram_size = 128 * 1024,
456 .n_gpnvms = 2,
457 .n_banks = 1,
458 {
459 /* .bank[0] = {*/
460 {
461 .probed = false,
462 .pChip = NULL,
463 .pBank = NULL,
464 .bank_number = 0,
465 .base_address = FLASH_BANK_BASE_S,
466 .controller_address = 0x400e0a00,
467 .flash_wait_states = 5,
468 .present = true,
469 .size_bytes = 1024 * 1024,
470 .nsectors = 128,
471 .sector_size = 8192,
472 .page_size = 512,
473 },
474 /* .bank[1] = {*/
475 {
476 .present = false,
477 .probed = false,
478 .bank_number = 1,
479
480 },
481 },
482 },
483
484 /* Start at91sam4n* series */
485 /*atsam4n8a - LQFP48/QFN48*/
486 {
487 .chipid_cidr = 0x293B0AE0,
488 .name = "at91sam4n8a",
489 .total_flash_size = 512 * 1024,
490 .total_sram_size = 64 * 1024,
491 .n_gpnvms = 2,
492 .n_banks = 1,
493 {
494 /* .bank[0] = {*/
495 {
496 .probed = false,
497 .pChip = NULL,
498 .pBank = NULL,
499 .bank_number = 0,
500 .base_address = FLASH_BANK_BASE_S,
501 .controller_address = 0x400e0a00,
502 .flash_wait_states = 5,
503 .present = true,
504 .size_bytes = 512 * 1024,
505 .nsectors = 64,
506 .sector_size = 8192,
507 .page_size = 512,
508 },
509 /* .bank[1] = {*/
510 {
511 .present = false,
512 .probed = false,
513 .bank_number = 1,
514
515 },
516 },
517 },
518 /*atsam4n8b - LQFP64/QFN64*/
519 {
520 .chipid_cidr = 0x294B0AE0,
521 .name = "at91sam4n8b",
522 .total_flash_size = 512 * 1024,
523 .total_sram_size = 64 * 1024,
524 .n_gpnvms = 2,
525 .n_banks = 1,
526 {
527 /* .bank[0] = {*/
528 {
529 .probed = false,
530 .pChip = NULL,
531 .pBank = NULL,
532 .bank_number = 0,
533 .base_address = FLASH_BANK_BASE_S,
534 .controller_address = 0x400e0a00,
535 .flash_wait_states = 5,
536 .present = true,
537 .size_bytes = 512 * 1024,
538 .nsectors = 64,
539 .sector_size = 8192,
540 .page_size = 512,
541 },
542 /* .bank[1] = {*/
543 {
544 .present = false,
545 .probed = false,
546 .bank_number = 1,
547
548 },
549 },
550 },
551 /*atsam4n8c - LQFP100/TFBGA100/VFBGA100*/
552 {
553 .chipid_cidr = 0x295B0AE0,
554 .name = "at91sam4n8c",
555 .total_flash_size = 512 * 1024,
556 .total_sram_size = 64 * 1024,
557 .n_gpnvms = 2,
558 .n_banks = 1,
559 {
560 /* .bank[0] = {*/
561 {
562 .probed = false,
563 .pChip = NULL,
564 .pBank = NULL,
565 .bank_number = 0,
566 .base_address = FLASH_BANK_BASE_S,
567 .controller_address = 0x400e0a00,
568 .flash_wait_states = 5,
569 .present = true,
570 .size_bytes = 512 * 1024,
571 .nsectors = 64,
572 .sector_size = 8192,
573 .page_size = 512,
574 },
575 /* .bank[1] = {*/
576 {
577 .present = false,
578 .probed = false,
579 .bank_number = 1,
580
581 },
582 },
583 },
584 /*atsam4n16b - LQFP64/QFN64*/
585 {
586 .chipid_cidr = 0x29460CE0,
587 .name = "at91sam4n16b",
588 .total_flash_size = 1024 * 1024,
589 .total_sram_size = 80 * 1024,
590 .n_gpnvms = 2,
591 .n_banks = 1,
592 {
593 /* .bank[0] = {*/
594 {
595 .probed = false,
596 .pChip = NULL,
597 .pBank = NULL,
598 .bank_number = 0,
599 .base_address = FLASH_BANK_BASE_S,
600 .controller_address = 0x400e0a00,
601 .flash_wait_states = 5,
602 .present = true,
603 .size_bytes = 1024 * 1024,
604 .nsectors = 128,
605 .sector_size = 8192,
606 .page_size = 512,
607 },
608 /* .bank[1] = {*/
609 {
610 .present = false,
611 .probed = false,
612 .bank_number = 1,
613
614 },
615 },
616 },
617 /*atsam4n16c - LQFP100/TFBGA100/VFBGA100*/
618 {
619 .chipid_cidr = 0x29560CE0,
620 .name = "at91sam4n16c",
621 .total_flash_size = 1024 * 1024,
622 .total_sram_size = 80 * 1024,
623 .n_gpnvms = 2,
624 .n_banks = 1,
625 {
626 /* .bank[0] = {*/
627 {
628 .probed = false,
629 .pChip = NULL,
630 .pBank = NULL,
631 .bank_number = 0,
632 .base_address = FLASH_BANK_BASE_S,
633 .controller_address = 0x400e0a00,
634 .flash_wait_states = 5,
635 .present = true,
636 .size_bytes = 1024 * 1024,
637 .nsectors = 128,
638 .sector_size = 8192,
639 .page_size = 512,
640 },
641 /* .bank[1] = {*/
642 {
643 .present = false,
644 .probed = false,
645 .bank_number = 1,
646
647 },
648 },
649 },
650
651 /* Start at91sam4s* series */
652 /*atsam4s16c - LQFP100/BGA100*/
653 {
654 .chipid_cidr = 0x28AC0CE0,
655 .name = "at91sam4s16c",
656 .total_flash_size = 1024 * 1024,
657 .total_sram_size = 128 * 1024,
658 .n_gpnvms = 2,
659 .n_banks = 1,
660 {
661 /* .bank[0] = {*/
662 {
663 .probed = false,
664 .pChip = NULL,
665 .pBank = NULL,
666 .bank_number = 0,
667 .base_address = FLASH_BANK_BASE_S,
668 .controller_address = 0x400e0a00,
669 .flash_wait_states = 5,
670 .present = true,
671 .size_bytes = 1024 * 1024,
672 .nsectors = 128,
673 .sector_size = 8192,
674 .page_size = 512,
675 },
676 /* .bank[1] = {*/
677 {
678 .present = false,
679 .probed = false,
680 .bank_number = 1,
681
682 },
683 },
684 },
685 /*at91sam4sa16c - TFBGA100/VFBGA100/LQFP100*/
686 {
687 .chipid_cidr = 0x28a70ce0,
688 .name = "at91sam4sa16c",
689 .total_flash_size = 1024 * 1024,
690 .total_sram_size = 160 * 1024,
691 .n_gpnvms = 2,
692 .n_banks = 1,
693
694 /* .bank[0] = { */
695 {
696 {
697 .probed = false,
698 .pChip = NULL,
699 .pBank = NULL,
700 .bank_number = 0,
701 .base_address = FLASH_BANK_BASE_S,
702 .controller_address = 0x400e0a00,
703 .flash_wait_states = 5,
704 .present = true,
705 .size_bytes = 1024 * 1024,
706 .nsectors = 128,
707 .sector_size = 8192,
708 .page_size = 512,
709 },
710 /* .bank[1] = {*/
711 {
712 .present = false,
713 .probed = false,
714 .bank_number = 1,
715
716 },
717 },
718 },
719 /*atsam4s16b - LQFP64/QFN64/WLCSP64*/
720 {
721 .chipid_cidr = 0x289C0CE0,
722 .name = "at91sam4s16b",
723 .total_flash_size = 1024 * 1024,
724 .total_sram_size = 128 * 1024,
725 .n_gpnvms = 2,
726 .n_banks = 1,
727 {
728 /* .bank[0] = {*/
729 {
730 .probed = false,
731 .pChip = NULL,
732 .pBank = NULL,
733 .bank_number = 0,
734 .base_address = FLASH_BANK_BASE_S,
735 .controller_address = 0x400e0a00,
736 .flash_wait_states = 5,
737 .present = true,
738 .size_bytes = 1024 * 1024,
739 .nsectors = 128,
740 .sector_size = 8192,
741 .page_size = 512,
742 },
743 /* .bank[1] = {*/
744 {
745 .present = false,
746 .probed = false,
747 .bank_number = 1,
748
749 },
750 },
751 },
752 /*atsam4sa16b - LQFP64/QFN64*/
753 {
754 .chipid_cidr = 0x28970CE0,
755 .name = "at91sam4sa16b",
756 .total_flash_size = 1024 * 1024,
757 .total_sram_size = 160 * 1024,
758 .n_gpnvms = 2,
759 .n_banks = 1,
760 {
761 /* .bank[0] = {*/
762 {
763 .probed = false,
764 .pChip = NULL,
765 .pBank = NULL,
766 .bank_number = 0,
767 .base_address = FLASH_BANK_BASE_S,
768 .controller_address = 0x400e0a00,
769 .flash_wait_states = 5,
770 .present = true,
771 .size_bytes = 1024 * 1024,
772 .nsectors = 128,
773 .sector_size = 8192,
774 .page_size = 512,
775 },
776 /* .bank[1] = {*/
777 {
778 .present = false,
779 .probed = false,
780 .bank_number = 1,
781
782 },
783 },
784 },
785 /*atsam4s16a - LQFP48/QFN48*/
786 {
787 .chipid_cidr = 0x288C0CE0,
788 .name = "at91sam4s16a",
789 .total_flash_size = 1024 * 1024,
790 .total_sram_size = 128 * 1024,
791 .n_gpnvms = 2,
792 .n_banks = 1,
793 {
794 /* .bank[0] = {*/
795 {
796 .probed = false,
797 .pChip = NULL,
798 .pBank = NULL,
799 .bank_number = 0,
800 .base_address = FLASH_BANK_BASE_S,
801 .controller_address = 0x400e0a00,
802 .flash_wait_states = 5,
803 .present = true,
804 .size_bytes = 1024 * 1024,
805 .nsectors = 128,
806 .sector_size = 8192,
807 .page_size = 512,
808 },
809 /* .bank[1] = {*/
810 {
811 .present = false,
812 .probed = false,
813 .bank_number = 1,
814
815 },
816 },
817 },
818 /*atsam4s8c - LQFP100/BGA100*/
819 {
820 .chipid_cidr = 0x28AC0AE0,
821 .name = "at91sam4s8c",
822 .total_flash_size = 512 * 1024,
823 .total_sram_size = 128 * 1024,
824 .n_gpnvms = 2,
825 .n_banks = 1,
826 {
827 /* .bank[0] = {*/
828 {
829 .probed = false,
830 .pChip = NULL,
831 .pBank = NULL,
832 .bank_number = 0,
833 .base_address = FLASH_BANK_BASE_S,
834 .controller_address = 0x400e0a00,
835 .flash_wait_states = 5,
836 .present = true,
837 .size_bytes = 512 * 1024,
838 .nsectors = 64,
839 .sector_size = 8192,
840 .page_size = 512,
841 },
842 /* .bank[1] = {*/
843 {
844 .present = false,
845 .probed = false,
846 .bank_number = 1,
847
848 },
849 },
850 },
851 /*atsam4s8b - LQFP64/QFN64/WLCSP64*/
852 {
853 .chipid_cidr = 0x289C0AE0,
854 .name = "at91sam4s8b",
855 .total_flash_size = 512 * 1024,
856 .total_sram_size = 128 * 1024,
857 .n_gpnvms = 2,
858 .n_banks = 1,
859 {
860 /* .bank[0] = {*/
861 {
862 .probed = false,
863 .pChip = NULL,
864 .pBank = NULL,
865 .bank_number = 0,
866 .base_address = FLASH_BANK_BASE_S,
867 .controller_address = 0x400e0a00,
868 .flash_wait_states = 5,
869 .present = true,
870 .size_bytes = 512 * 1024,
871 .nsectors = 64,
872 .sector_size = 8192,
873 .page_size = 512,
874 },
875 /* .bank[1] = {*/
876 {
877 .present = false,
878 .probed = false,
879 .bank_number = 1,
880
881 },
882 },
883 },
884 /*atsam4s8a - LQFP48/BGA48*/
885 {
886 .chipid_cidr = 0x288C0AE0,
887 .name = "at91sam4s8a",
888 .total_flash_size = 512 * 1024,
889 .total_sram_size = 128 * 1024,
890 .n_gpnvms = 2,
891 .n_banks = 1,
892 {
893 /* .bank[0] = {*/
894 {
895 .probed = false,
896 .pChip = NULL,
897 .pBank = NULL,
898 .bank_number = 0,
899 .base_address = FLASH_BANK_BASE_S,
900 .controller_address = 0x400e0a00,
901 .flash_wait_states = 5,
902 .present = true,
903 .size_bytes = 512 * 1024,
904 .nsectors = 64,
905 .sector_size = 8192,
906 .page_size = 512,
907 },
908 /* .bank[1] = {*/
909 {
910 .present = false,
911 .probed = false,
912 .bank_number = 1,
913
914 },
915 },
916 },
917
918 /*atsam4s4c - LQFP100/BGA100*/
919 {
920 .chipid_cidr = 0x28ab09e0,
921 .name = "at91sam4s4c",
922 .total_flash_size = 256 * 1024,
923 .total_sram_size = 64 * 1024,
924 .n_gpnvms = 2,
925 .n_banks = 1,
926 {
927 /* .bank[0] = {*/
928 {
929 .probed = false,
930 .pChip = NULL,
931 .pBank = NULL,
932 .bank_number = 0,
933 .base_address = FLASH_BANK_BASE_S,
934 .controller_address = 0x400e0a00,
935 .flash_wait_states = 5,
936 .present = true,
937 .size_bytes = 256 * 1024,
938 .nsectors = 32,
939 .sector_size = 8192,
940 .page_size = 512,
941 },
942 /* .bank[1] = {*/
943 {
944 .present = false,
945 .probed = false,
946 .bank_number = 1,
947
948 },
949 },
950 },
951
952 /*atsam4s4b - LQFP64/QFN64/WLCSP64*/
953 {
954 .chipid_cidr = 0x289b09e0,
955 .name = "at91sam4s4b",
956 .total_flash_size = 256 * 1024,
957 .total_sram_size = 64 * 1024,
958 .n_gpnvms = 2,
959 .n_banks = 1,
960 {
961 /* .bank[0] = {*/
962 {
963 .probed = false,
964 .pChip = NULL,
965 .pBank = NULL,
966 .bank_number = 0,
967 .base_address = FLASH_BANK_BASE_S,
968 .controller_address = 0x400e0a00,
969 .flash_wait_states = 5,
970 .present = true,
971 .size_bytes = 256 * 1024,
972 .nsectors = 32,
973 .sector_size = 8192,
974 .page_size = 512,
975 },
976 /* .bank[1] = {*/
977 {
978 .present = false,
979 .probed = false,
980 .bank_number = 1,
981
982 },
983 },
984 },
985
986 /*atsam4s4a - LQFP48/QFN48*/
987 {
988 .chipid_cidr = 0x288b09e0,
989 .name = "at91sam4s4a",
990 .total_flash_size = 256 * 1024,
991 .total_sram_size = 64 * 1024,
992 .n_gpnvms = 2,
993 .n_banks = 1,
994 {
995 /* .bank[0] = {*/
996 {
997 .probed = false,
998 .pChip = NULL,
999 .pBank = NULL,
1000 .bank_number = 0,
1001 .base_address = FLASH_BANK_BASE_S,
1002 .controller_address = 0x400e0a00,
1003 .flash_wait_states = 5,
1004 .present = true,
1005 .size_bytes = 256 * 1024,
1006 .nsectors = 32,
1007 .sector_size = 8192,
1008 .page_size = 512,
1009 },
1010 /* .bank[1] = {*/
1011 {
1012 .present = false,
1013 .probed = false,
1014 .bank_number = 1,
1015
1016 },
1017 },
1018 },
1019
1020 /*atsam4s2c - LQFP100/BGA100*/
1021 {
1022 .chipid_cidr = 0x28ab07e0,
1023 .name = "at91sam4s2c",
1024 .total_flash_size = 128 * 1024,
1025 .total_sram_size = 64 * 1024,
1026 .n_gpnvms = 2,
1027 .n_banks = 1,
1028 {
1029 /* .bank[0] = {*/
1030 {
1031 .probed = false,
1032 .pChip = NULL,
1033 .pBank = NULL,
1034 .bank_number = 0,
1035 .base_address = FLASH_BANK_BASE_S,
1036 .controller_address = 0x400e0a00,
1037 .flash_wait_states = 5,
1038 .present = true,
1039 .size_bytes = 128 * 1024,
1040 .nsectors = 16,
1041 .sector_size = 8192,
1042 .page_size = 512,
1043 },
1044 /* .bank[1] = {*/
1045 {
1046 .present = false,
1047 .probed = false,
1048 .bank_number = 1,
1049
1050 },
1051 },
1052 },
1053
1054 /*atsam4s2b - LQPF64/QFN64/WLCSP64*/
1055 {
1056 .chipid_cidr = 0x289b07e0,
1057 .name = "at91sam4s2b",
1058 .total_flash_size = 128 * 1024,
1059 .total_sram_size = 64 * 1024,
1060 .n_gpnvms = 2,
1061 .n_banks = 1,
1062 {
1063 /* .bank[0] = {*/
1064 {
1065 .probed = false,
1066 .pChip = NULL,
1067 .pBank = NULL,
1068 .bank_number = 0,
1069 .base_address = FLASH_BANK_BASE_S,
1070 .controller_address = 0x400e0a00,
1071 .flash_wait_states = 5,
1072 .present = true,
1073 .size_bytes = 128 * 1024,
1074 .nsectors = 16,
1075 .sector_size = 8192,
1076 .page_size = 512,
1077 },
1078 /* .bank[1] = {*/
1079 {
1080 .present = false,
1081 .probed = false,
1082 .bank_number = 1,
1083
1084 },
1085 },
1086 },
1087
1088 /*atsam4s2a - LQFP48/QFN48*/
1089 {
1090 .chipid_cidr = 0x288b07e0,
1091 .name = "at91sam4s2a",
1092 .total_flash_size = 128 * 1024,
1093 .total_sram_size = 64 * 1024,
1094 .n_gpnvms = 2,
1095 .n_banks = 1,
1096 {
1097 /* .bank[0] = {*/
1098 {
1099 .probed = false,
1100 .pChip = NULL,
1101 .pBank = NULL,
1102 .bank_number = 0,
1103 .base_address = FLASH_BANK_BASE_S,
1104 .controller_address = 0x400e0a00,
1105 .flash_wait_states = 5,
1106 .present = true,
1107 .size_bytes = 128 * 1024,
1108 .nsectors = 16,
1109 .sector_size = 8192,
1110 .page_size = 512,
1111 },
1112 /* .bank[1] = {*/
1113 {
1114 .present = false,
1115 .probed = false,
1116 .bank_number = 1,
1117
1118 },
1119 },
1120 },
1121
1122 /*at91sam4sd32c - LQFP100/BGA100*/
1123 {
1124 .chipid_cidr = 0x29a70ee0,
1125 .name = "at91sam4sd32c",
1126 .total_flash_size = 2048 * 1024,
1127 .total_sram_size = 160 * 1024,
1128 .n_gpnvms = 3,
1129 .n_banks = 2,
1130
1131 /* .bank[0] = { */
1132 {
1133 {
1134 .probed = false,
1135 .pChip = NULL,
1136 .pBank = NULL,
1137 .bank_number = 0,
1138 .base_address = FLASH_BANK0_BASE_SD,
1139 .controller_address = 0x400e0a00,
1140 .flash_wait_states = 5,
1141 .present = true,
1142 .size_bytes = 1024 * 1024,
1143 .nsectors = 128,
1144 .sector_size = 8192,
1145 .page_size = 512,
1146 },
1147
1148 /* .bank[1] = { */
1149 {
1150 .probed = false,
1151 .pChip = NULL,
1152 .pBank = NULL,
1153 .bank_number = 1,
1154 .base_address = FLASH_BANK1_BASE_2048K_SD,
1155 .controller_address = 0x400e0c00,
1156 .flash_wait_states = 5,
1157 .present = true,
1158 .size_bytes = 1024 * 1024,
1159 .nsectors = 128,
1160 .sector_size = 8192,
1161 .page_size = 512,
1162 },
1163 },
1164 },
1165
1166 /*at91sam4sd32b - LQFP64/BGA64*/
1167 {
1168 .chipid_cidr = 0x29970ee0,
1169 .name = "at91sam4sd32b",
1170 .total_flash_size = 2048 * 1024,
1171 .total_sram_size = 160 * 1024,
1172 .n_gpnvms = 3,
1173 .n_banks = 2,
1174
1175 /* .bank[0] = { */
1176 {
1177 {
1178 .probed = false,
1179 .pChip = NULL,
1180 .pBank = NULL,
1181 .bank_number = 0,
1182 .base_address = FLASH_BANK0_BASE_SD,
1183 .controller_address = 0x400e0a00,
1184 .flash_wait_states = 5,
1185 .present = true,
1186 .size_bytes = 1024 * 1024,
1187 .nsectors = 128,
1188 .sector_size = 8192,
1189 .page_size = 512,
1190 },
1191
1192 /* .bank[1] = { */
1193 {
1194 .probed = false,
1195 .pChip = NULL,
1196 .pBank = NULL,
1197 .bank_number = 1,
1198 .base_address = FLASH_BANK1_BASE_2048K_SD,
1199 .controller_address = 0x400e0c00,
1200 .flash_wait_states = 5,
1201 .present = true,
1202 .size_bytes = 1024 * 1024,
1203 .nsectors = 128,
1204 .sector_size = 8192,
1205 .page_size = 512,
1206 },
1207 },
1208 },
1209
1210 /*at91sam4sd16c - LQFP100/BGA100*/
1211 {
1212 .chipid_cidr = 0x29a70ce0,
1213 .name = "at91sam4sd16c",
1214 .total_flash_size = 1024 * 1024,
1215 .total_sram_size = 160 * 1024,
1216 .n_gpnvms = 3,
1217 .n_banks = 2,
1218
1219 /* .bank[0] = { */
1220 {
1221 {
1222 .probed = false,
1223 .pChip = NULL,
1224 .pBank = NULL,
1225 .bank_number = 0,
1226 .base_address = FLASH_BANK0_BASE_SD,
1227 .controller_address = 0x400e0a00,
1228 .flash_wait_states = 5,
1229 .present = true,
1230 .size_bytes = 512 * 1024,
1231 .nsectors = 64,
1232 .sector_size = 8192,
1233 .page_size = 512,
1234 },
1235
1236 /* .bank[1] = { */
1237 {
1238 .probed = false,
1239 .pChip = NULL,
1240 .pBank = NULL,
1241 .bank_number = 1,
1242 .base_address = FLASH_BANK1_BASE_1024K_SD,
1243 .controller_address = 0x400e0c00,
1244 .flash_wait_states = 5,
1245 .present = true,
1246 .size_bytes = 512 * 1024,
1247 .nsectors = 64,
1248 .sector_size = 8192,
1249 .page_size = 512,
1250 },
1251 },
1252 },
1253
1254 /*at91sam4sd16b - LQFP64/BGA64*/
1255 {
1256 .chipid_cidr = 0x29970ce0,
1257 .name = "at91sam4sd16b",
1258 .total_flash_size = 1024 * 1024,
1259 .total_sram_size = 160 * 1024,
1260 .n_gpnvms = 3,
1261 .n_banks = 2,
1262
1263 /* .bank[0] = { */
1264 {
1265 {
1266 .probed = false,
1267 .pChip = NULL,
1268 .pBank = NULL,
1269 .bank_number = 0,
1270 .base_address = FLASH_BANK0_BASE_SD,
1271 .controller_address = 0x400e0a00,
1272 .flash_wait_states = 5,
1273 .present = true,
1274 .size_bytes = 512 * 1024,
1275 .nsectors = 64,
1276 .sector_size = 8192,
1277 .page_size = 512,
1278 },
1279
1280 /* .bank[1] = { */
1281 {
1282 .probed = false,
1283 .pChip = NULL,
1284 .pBank = NULL,
1285 .bank_number = 1,
1286 .base_address = FLASH_BANK1_BASE_1024K_SD,
1287 .controller_address = 0x400e0c00,
1288 .flash_wait_states = 5,
1289 .present = true,
1290 .size_bytes = 512 * 1024,
1291 .nsectors = 64,
1292 .sector_size = 8192,
1293 .page_size = 512,
1294 },
1295 },
1296 },
1297
1298 /* atsamg53n19 */
1299 {
1300 .chipid_cidr = 0x247e0ae0,
1301 .name = "atsamg53n19",
1302 .total_flash_size = 512 * 1024,
1303 .total_sram_size = 96 * 1024,
1304 .n_gpnvms = 2,
1305 .n_banks = 1,
1306
1307 /* .bank[0] = {*/
1308 {
1309 {
1310 .probed = false,
1311 .pChip = NULL,
1312 .pBank = NULL,
1313 .bank_number = 0,
1314 .base_address = FLASH_BANK_BASE_S,
1315 .controller_address = 0x400e0a00,
1316 .flash_wait_states = 5,
1317 .present = true,
1318 .size_bytes = 512 * 1024,
1319 .nsectors = 64,
1320 .sector_size = 8192,
1321 .page_size = 512,
1322 },
1323 /* .bank[1] = {*/
1324 {
1325 .present = false,
1326 .probed = false,
1327 .bank_number = 1,
1328
1329 },
1330 }
1331 },
1332
1333 /* atsamg55g19 Rev.A */
1334 {
1335 .chipid_cidr = 0x24470ae0,
1336 .name = "atsamg55g19",
1337 .total_flash_size = 512 * 1024,
1338 .total_sram_size = 160 * 1024,
1339 .n_gpnvms = 2,
1340 .n_banks = 1,
1341
1342 {
1343 /* .bank[0] = */
1344 {
1345 .probed = false,
1346 .pChip = NULL,
1347 .pBank = NULL,
1348 .bank_number = 0,
1349 .base_address = FLASH_BANK_BASE_S,
1350 .controller_address = 0x400e0a00,
1351 .flash_wait_states = 5,
1352 .present = true,
1353 .size_bytes = 512 * 1024,
1354 .nsectors = 64,
1355 .sector_size = 8192,
1356 .page_size = 512,
1357 },
1358 /* .bank[1] = */
1359 {
1360 .present = false,
1361 .probed = false,
1362 .bank_number = 1,
1363 },
1364 }
1365 },
1366
1367 /* atsamg55g19 Rev.B */
1368 {
1369 .chipid_cidr = 0x24470ae1,
1370 .name = "atsamg55g19b",
1371 .total_flash_size = 512 * 1024,
1372 .total_sram_size = 160 * 1024,
1373 .n_gpnvms = 2,
1374 .n_banks = 1,
1375
1376 {
1377 /* .bank[0] = */
1378 {
1379 .probed = false,
1380 .pChip = NULL,
1381 .pBank = NULL,
1382 .bank_number = 0,
1383 .base_address = FLASH_BANK_BASE_S,
1384 .controller_address = 0x400e0a00,
1385 .flash_wait_states = 5,
1386 .present = true,
1387 .size_bytes = 512 * 1024,
1388 .nsectors = 64,
1389 .sector_size = 8192,
1390 .page_size = 512,
1391 },
1392 /* .bank[1] = */
1393 {
1394 .present = false,
1395 .probed = false,
1396 .bank_number = 1,
1397 },
1398 }
1399 },
1400
1401 /* atsamg55j19 Rev.A */
1402 {
1403 .chipid_cidr = 0x24570ae0,
1404 .name = "atsamg55j19",
1405 .total_flash_size = 512 * 1024,
1406 .total_sram_size = 160 * 1024,
1407 .n_gpnvms = 2,
1408 .n_banks = 1,
1409
1410 {
1411 /* .bank[0] = */
1412 {
1413 .probed = false,
1414 .pChip = NULL,
1415 .pBank = NULL,
1416 .bank_number = 0,
1417 .base_address = FLASH_BANK_BASE_S,
1418 .controller_address = 0x400e0a00,
1419 .flash_wait_states = 5,
1420 .present = true,
1421 .size_bytes = 512 * 1024,
1422 .nsectors = 64,
1423 .sector_size = 8192,
1424 .page_size = 512,
1425 },
1426 /* .bank[1] = */
1427 {
1428 .present = false,
1429 .probed = false,
1430 .bank_number = 1,
1431 },
1432 }
1433 },
1434
1435 /* atsamg55j19 Rev.B */
1436 {
1437 .chipid_cidr = 0x24570ae1,
1438 .name = "atsamg55j19b",
1439 .total_flash_size = 512 * 1024,
1440 .total_sram_size = 160 * 1024,
1441 .n_gpnvms = 2,
1442 .n_banks = 1,
1443
1444 {
1445 /* .bank[0] = */
1446 {
1447 .probed = false,
1448 .pChip = NULL,
1449 .pBank = NULL,
1450 .bank_number = 0,
1451 .base_address = FLASH_BANK_BASE_S,
1452 .controller_address = 0x400e0a00,
1453 .flash_wait_states = 5,
1454 .present = true,
1455 .size_bytes = 512 * 1024,
1456 .nsectors = 64,
1457 .sector_size = 8192,
1458 .page_size = 512,
1459 },
1460 /* .bank[1] = */
1461 {
1462 .present = false,
1463 .probed = false,
1464 .bank_number = 1,
1465 },
1466 }
1467 },
1468
1469 /* terminate */
1470 {
1471 .chipid_cidr = 0,
1472 .name = NULL,
1473 }
1474 };
1475
1476 /* Globals above */
1477 /***********************************************************************
1478 **********************************************************************
1479 **********************************************************************
1480 **********************************************************************
1481 **********************************************************************
1482 **********************************************************************/
1483 /* *ATMEL* style code - from the SAM4 driver code */
1484
1485 /**
1486 * Get the current status of the EEFC and
1487 * the value of some status bits (LOCKE, PROGE).
1488 * @param pPrivate - info about the bank
1489 * @param v - result goes here
1490 */
1491 static int EFC_GetStatus(struct sam4_bank_private *pPrivate, uint32_t *v)
1492 {
1493 int r;
1494 r = target_read_u32(pPrivate->pChip->target,
1495 pPrivate->controller_address + offset_EFC_FSR,
1496 v);
1497 LOG_DEBUG("Status: 0x%08x (lockerror: %d, cmderror: %d, ready: %d)",
1498 (unsigned int)(*v),
1499 ((unsigned int)((*v >> 2) & 1)),
1500 ((unsigned int)((*v >> 1) & 1)),
1501 ((unsigned int)((*v >> 0) & 1)));
1502
1503 return r;
1504 }
1505
1506 /**
1507 * Get the result of the last executed command.
1508 * @param pPrivate - info about the bank
1509 * @param v - result goes here
1510 */
1511 static int EFC_GetResult(struct sam4_bank_private *pPrivate, uint32_t *v)
1512 {
1513 int r;
1514 uint32_t rv;
1515 r = target_read_u32(pPrivate->pChip->target,
1516 pPrivate->controller_address + offset_EFC_FRR,
1517 &rv);
1518 if (v)
1519 *v = rv;
1520 LOG_DEBUG("Result: 0x%08x", ((unsigned int)(rv)));
1521 return r;
1522 }
1523
1524 static int EFC_StartCommand(struct sam4_bank_private *pPrivate,
1525 unsigned command, unsigned argument)
1526 {
1527 uint32_t n, v;
1528 int r;
1529 int retry;
1530
1531 retry = 0;
1532 do_retry:
1533
1534 /* Check command & argument */
1535 switch (command) {
1536
1537 case AT91C_EFC_FCMD_WP:
1538 case AT91C_EFC_FCMD_WPL:
1539 case AT91C_EFC_FCMD_EWP:
1540 case AT91C_EFC_FCMD_EWPL:
1541 /* case AT91C_EFC_FCMD_EPL: */
1542 case AT91C_EFC_FCMD_EPA:
1543 case AT91C_EFC_FCMD_SLB:
1544 case AT91C_EFC_FCMD_CLB:
1545 n = (pPrivate->size_bytes / pPrivate->page_size);
1546 if (argument >= n)
1547 LOG_ERROR("*BUG*: Embedded flash has only %u pages", (unsigned)(n));
1548 break;
1549
1550 case AT91C_EFC_FCMD_SFB:
1551 case AT91C_EFC_FCMD_CFB:
1552 if (argument >= pPrivate->pChip->details.n_gpnvms) {
1553 LOG_ERROR("*BUG*: Embedded flash has only %d GPNVMs",
1554 pPrivate->pChip->details.n_gpnvms);
1555 }
1556 break;
1557
1558 case AT91C_EFC_FCMD_GETD:
1559 case AT91C_EFC_FCMD_EA:
1560 case AT91C_EFC_FCMD_GLB:
1561 case AT91C_EFC_FCMD_GFB:
1562 case AT91C_EFC_FCMD_STUI:
1563 case AT91C_EFC_FCMD_SPUI:
1564 if (argument != 0)
1565 LOG_ERROR("Argument is meaningless for cmd: %d", command);
1566 break;
1567 default:
1568 LOG_ERROR("Unknown command %d", command);
1569 break;
1570 }
1571
1572 if (command == AT91C_EFC_FCMD_SPUI) {
1573 /* this is a very special situation. */
1574 /* Situation (1) - error/retry - see below */
1575 /* And we are being called recursively */
1576 /* Situation (2) - normal, finished reading unique id */
1577 } else {
1578 /* it should be "ready" */
1579 EFC_GetStatus(pPrivate, &v);
1580 if (v & 1) {
1581 /* then it is ready */
1582 /* we go on */
1583 } else {
1584 if (retry) {
1585 /* we have done this before */
1586 /* the controller is not responding. */
1587 LOG_ERROR("flash controller(%d) is not ready! Error",
1588 pPrivate->bank_number);
1589 return ERROR_FAIL;
1590 } else {
1591 retry++;
1592 LOG_ERROR("Flash controller(%d) is not ready, attempting reset",
1593 pPrivate->bank_number);
1594 /* we do that by issuing the *STOP* command */
1595 EFC_StartCommand(pPrivate, AT91C_EFC_FCMD_SPUI, 0);
1596 /* above is recursive, and further recursion is blocked by */
1597 /* if (command == AT91C_EFC_FCMD_SPUI) above */
1598 goto do_retry;
1599 }
1600 }
1601 }
1602
1603 v = (0x5A << 24) | (argument << 8) | command;
1604 LOG_DEBUG("Command: 0x%08x", ((unsigned int)(v)));
1605 r = target_write_u32(pPrivate->pBank->target,
1606 pPrivate->controller_address + offset_EFC_FCR, v);
1607 if (r != ERROR_OK)
1608 LOG_DEBUG("Error Write failed");
1609 return r;
1610 }
1611
1612 /**
1613 * Performs the given command and wait until its completion (or an error).
1614 * @param pPrivate - info about the bank
1615 * @param command - Command to perform.
1616 * @param argument - Optional command argument.
1617 * @param status - put command status bits here
1618 */
1619 static int EFC_PerformCommand(struct sam4_bank_private *pPrivate,
1620 unsigned command,
1621 unsigned argument,
1622 uint32_t *status)
1623 {
1624
1625 int r;
1626 uint32_t v;
1627 int64_t ms_now, ms_end;
1628
1629 /* default */
1630 if (status)
1631 *status = 0;
1632
1633 r = EFC_StartCommand(pPrivate, command, argument);
1634 if (r != ERROR_OK)
1635 return r;
1636
1637 ms_end = 10000 + timeval_ms();
1638
1639 do {
1640 r = EFC_GetStatus(pPrivate, &v);
1641 if (r != ERROR_OK)
1642 return r;
1643 ms_now = timeval_ms();
1644 if (ms_now > ms_end) {
1645 /* error */
1646 LOG_ERROR("Command timeout");
1647 return ERROR_FAIL;
1648 }
1649 } while ((v & 1) == 0);
1650
1651 /* error bits.. */
1652 if (status)
1653 *status = (v & 0x6);
1654 return ERROR_OK;
1655
1656 }
1657
1658 /**
1659 * Read the unique ID.
1660 * @param pPrivate - info about the bank
1661 * The unique ID is stored in the 'pPrivate' structure.
1662 */
1663 static int FLASHD_ReadUniqueID(struct sam4_bank_private *pPrivate)
1664 {
1665 int r;
1666 uint32_t v;
1667 int x;
1668 /* assume 0 */
1669 pPrivate->pChip->cfg.unique_id[0] = 0;
1670 pPrivate->pChip->cfg.unique_id[1] = 0;
1671 pPrivate->pChip->cfg.unique_id[2] = 0;
1672 pPrivate->pChip->cfg.unique_id[3] = 0;
1673
1674 LOG_DEBUG("Begin");
1675 r = EFC_StartCommand(pPrivate, AT91C_EFC_FCMD_STUI, 0);
1676 if (r < 0)
1677 return r;
1678
1679 for (x = 0; x < 4; x++) {
1680 r = target_read_u32(pPrivate->pChip->target,
1681 pPrivate->pBank->base + (x * 4),
1682 &v);
1683 if (r < 0)
1684 return r;
1685 pPrivate->pChip->cfg.unique_id[x] = v;
1686 }
1687
1688 r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_SPUI, 0, NULL);
1689 LOG_DEBUG("End: R=%d, id = 0x%08x, 0x%08x, 0x%08x, 0x%08x",
1690 r,
1691 (unsigned int)(pPrivate->pChip->cfg.unique_id[0]),
1692 (unsigned int)(pPrivate->pChip->cfg.unique_id[1]),
1693 (unsigned int)(pPrivate->pChip->cfg.unique_id[2]),
1694 (unsigned int)(pPrivate->pChip->cfg.unique_id[3]));
1695 return r;
1696
1697 }
1698
1699 /**
1700 * Erases the entire flash.
1701 * @param pPrivate - the info about the bank.
1702 */
1703 static int FLASHD_EraseEntireBank(struct sam4_bank_private *pPrivate)
1704 {
1705 LOG_DEBUG("Here");
1706 return EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_EA, 0, NULL);
1707 }
1708
1709 /**
1710 * Erases the entire flash.
1711 * @param pPrivate - the info about the bank.
1712 */
1713 static int FLASHD_ErasePages(struct sam4_bank_private *pPrivate,
1714 int firstPage,
1715 int numPages,
1716 uint32_t *status)
1717 {
1718 LOG_DEBUG("Here");
1719 uint8_t erasePages;
1720 switch (numPages) {
1721 case 4:
1722 erasePages = 0x00;
1723 break;
1724 case 8:
1725 erasePages = 0x01;
1726 break;
1727 case 16:
1728 erasePages = 0x02;
1729 break;
1730 case 32:
1731 erasePages = 0x03;
1732 break;
1733 default:
1734 erasePages = 0x00;
1735 break;
1736 }
1737
1738 /* AT91C_EFC_FCMD_EPA
1739 * According to the datasheet FARG[15:2] defines the page from which
1740 * the erase will start.This page must be modulo 4, 8, 16 or 32
1741 * according to the number of pages to erase. FARG[1:0] defines the
1742 * number of pages to be erased. Previously (firstpage << 2) was used
1743 * to conform to this, seems it should not be shifted...
1744 */
1745 return EFC_PerformCommand(pPrivate,
1746 /* send Erase Page */
1747 AT91C_EFC_FCMD_EPA,
1748 (firstPage) | erasePages,
1749 status);
1750 }
1751
1752 /**
1753 * Gets current GPNVM state.
1754 * @param pPrivate - info about the bank.
1755 * @param gpnvm - GPNVM bit index.
1756 * @param puthere - result stored here.
1757 */
1758 /* ------------------------------------------------------------------------------ */
1759 static int FLASHD_GetGPNVM(struct sam4_bank_private *pPrivate, unsigned gpnvm, unsigned *puthere)
1760 {
1761 uint32_t v;
1762 int r;
1763
1764 LOG_DEBUG("Here");
1765 if (pPrivate->bank_number != 0) {
1766 LOG_ERROR("GPNVM only works with Bank0");
1767 return ERROR_FAIL;
1768 }
1769
1770 if (gpnvm >= pPrivate->pChip->details.n_gpnvms) {
1771 LOG_ERROR("Invalid GPNVM %d, max: %d, ignored",
1772 gpnvm, pPrivate->pChip->details.n_gpnvms);
1773 return ERROR_FAIL;
1774 }
1775
1776 /* Get GPNVMs status */
1777 r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_GFB, 0, NULL);
1778 if (r != ERROR_OK) {
1779 LOG_ERROR("Failed");
1780 return r;
1781 }
1782
1783 r = EFC_GetResult(pPrivate, &v);
1784
1785 if (puthere) {
1786 /* Check if GPNVM is set */
1787 /* get the bit and make it a 0/1 */
1788 *puthere = (v >> gpnvm) & 1;
1789 }
1790
1791 return r;
1792 }
1793
1794 /**
1795 * Clears the selected GPNVM bit.
1796 * @param pPrivate info about the bank
1797 * @param gpnvm GPNVM index.
1798 * @returns 0 if successful; otherwise returns an error code.
1799 */
1800 static int FLASHD_ClrGPNVM(struct sam4_bank_private *pPrivate, unsigned gpnvm)
1801 {
1802 int r;
1803 unsigned v;
1804
1805 LOG_DEBUG("Here");
1806 if (pPrivate->bank_number != 0) {
1807 LOG_ERROR("GPNVM only works with Bank0");
1808 return ERROR_FAIL;
1809 }
1810
1811 if (gpnvm >= pPrivate->pChip->details.n_gpnvms) {
1812 LOG_ERROR("Invalid GPNVM %d, max: %d, ignored",
1813 gpnvm, pPrivate->pChip->details.n_gpnvms);
1814 return ERROR_FAIL;
1815 }
1816
1817 r = FLASHD_GetGPNVM(pPrivate, gpnvm, &v);
1818 if (r != ERROR_OK) {
1819 LOG_DEBUG("Failed: %d", r);
1820 return r;
1821 }
1822 r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_CFB, gpnvm, NULL);
1823 LOG_DEBUG("End: %d", r);
1824 return r;
1825 }
1826
1827 /**
1828 * Sets the selected GPNVM bit.
1829 * @param pPrivate info about the bank
1830 * @param gpnvm GPNVM index.
1831 */
1832 static int FLASHD_SetGPNVM(struct sam4_bank_private *pPrivate, unsigned gpnvm)
1833 {
1834 int r;
1835 unsigned v;
1836
1837 if (pPrivate->bank_number != 0) {
1838 LOG_ERROR("GPNVM only works with Bank0");
1839 return ERROR_FAIL;
1840 }
1841
1842 if (gpnvm >= pPrivate->pChip->details.n_gpnvms) {
1843 LOG_ERROR("Invalid GPNVM %d, max: %d, ignored",
1844 gpnvm, pPrivate->pChip->details.n_gpnvms);
1845 return ERROR_FAIL;
1846 }
1847
1848 r = FLASHD_GetGPNVM(pPrivate, gpnvm, &v);
1849 if (r != ERROR_OK)
1850 return r;
1851 if (v) {
1852 /* already set */
1853 r = ERROR_OK;
1854 } else {
1855 /* set it */
1856 r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_SFB, gpnvm, NULL);
1857 }
1858 return r;
1859 }
1860
1861 /**
1862 * Returns a bit field (at most 64) of locked regions within a page.
1863 * @param pPrivate info about the bank
1864 * @param v where to store locked bits
1865 */
1866 static int FLASHD_GetLockBits(struct sam4_bank_private *pPrivate, uint32_t *v)
1867 {
1868 int r;
1869 LOG_DEBUG("Here");
1870 r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_GLB, 0, NULL);
1871 if (r == ERROR_OK) {
1872 EFC_GetResult(pPrivate, v);
1873 EFC_GetResult(pPrivate, v);
1874 EFC_GetResult(pPrivate, v);
1875 r = EFC_GetResult(pPrivate, v);
1876 }
1877 LOG_DEBUG("End: %d", r);
1878 return r;
1879 }
1880
1881 /**
1882 * Unlocks all the regions in the given address range.
1883 * @param pPrivate info about the bank
1884 * @param start_sector first sector to unlock
1885 * @param end_sector last (inclusive) to unlock
1886 */
1887
1888 static int FLASHD_Unlock(struct sam4_bank_private *pPrivate,
1889 unsigned start_sector,
1890 unsigned end_sector)
1891 {
1892 int r;
1893 uint32_t status;
1894 uint32_t pg;
1895 uint32_t pages_per_sector;
1896
1897 pages_per_sector = pPrivate->sector_size / pPrivate->page_size;
1898
1899 /* Unlock all pages */
1900 while (start_sector <= end_sector) {
1901 pg = start_sector * pages_per_sector;
1902
1903 r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_CLB, pg, &status);
1904 if (r != ERROR_OK)
1905 return r;
1906 start_sector++;
1907 }
1908
1909 return ERROR_OK;
1910 }
1911
1912 /**
1913 * Locks regions
1914 * @param pPrivate - info about the bank
1915 * @param start_sector - first sector to lock
1916 * @param end_sector - last sector (inclusive) to lock
1917 */
1918 static int FLASHD_Lock(struct sam4_bank_private *pPrivate,
1919 unsigned start_sector,
1920 unsigned end_sector)
1921 {
1922 uint32_t status;
1923 uint32_t pg;
1924 uint32_t pages_per_sector;
1925 int r;
1926
1927 pages_per_sector = pPrivate->sector_size / pPrivate->page_size;
1928
1929 /* Lock all pages */
1930 while (start_sector <= end_sector) {
1931 pg = start_sector * pages_per_sector;
1932
1933 r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_SLB, pg, &status);
1934 if (r != ERROR_OK)
1935 return r;
1936 start_sector++;
1937 }
1938 return ERROR_OK;
1939 }
1940
1941 /****** END SAM4 CODE ********/
1942
1943 /* begin helpful debug code */
1944 /* print the fieldname, the field value, in dec & hex, and return field value */
1945 static uint32_t sam4_reg_fieldname(struct sam4_chip *pChip,
1946 const char *regname,
1947 uint32_t value,
1948 unsigned shift,
1949 unsigned width)
1950 {
1951 uint32_t v;
1952 int hwidth, dwidth;
1953
1954
1955 /* extract the field */
1956 v = value >> shift;
1957 v = v & ((1 << width)-1);
1958 if (width <= 16) {
1959 hwidth = 4;
1960 dwidth = 5;
1961 } else {
1962 hwidth = 8;
1963 dwidth = 12;
1964 }
1965
1966 /* show the basics */
1967 LOG_USER_N("\t%*s: %*" PRIu32 " [0x%0*" PRIx32 "] ",
1968 REG_NAME_WIDTH, regname,
1969 dwidth, v,
1970 hwidth, v);
1971 return v;
1972 }
1973
1974 static const char _unknown[] = "unknown";
1975 static const char *const eproc_names[] = {
1976 "Cortex-M7", /* 0 */
1977 "arm946es", /* 1 */
1978 "arm7tdmi", /* 2 */
1979 "Cortex-M3", /* 3 */
1980 "arm920t", /* 4 */
1981 "arm926ejs", /* 5 */
1982 "Cortex-A5", /* 6 */
1983 "Cortex-M4", /* 7 */
1984 _unknown, /* 8 */
1985 _unknown, /* 9 */
1986 _unknown, /* 10 */
1987 _unknown, /* 11 */
1988 _unknown, /* 12 */
1989 _unknown, /* 13 */
1990 _unknown, /* 14 */
1991 _unknown, /* 15 */
1992 };
1993
1994 #define nvpsize2 nvpsize /* these two tables are identical */
1995 static const char *const nvpsize[] = {
1996 "none", /* 0 */
1997 "8K bytes", /* 1 */
1998 "16K bytes", /* 2 */
1999 "32K bytes", /* 3 */
2000 _unknown, /* 4 */
2001 "64K bytes", /* 5 */
2002 _unknown, /* 6 */
2003 "128K bytes", /* 7 */
2004 "160K bytes", /* 8 */
2005 "256K bytes", /* 9 */
2006 "512K bytes", /* 10 */
2007 _unknown, /* 11 */
2008 "1024K bytes", /* 12 */
2009 _unknown, /* 13 */
2010 "2048K bytes", /* 14 */
2011 _unknown, /* 15 */
2012 };
2013
2014 static const char *const sramsize[] = {
2015 "48K Bytes", /* 0 */
2016 "1K Bytes", /* 1 */
2017 "2K Bytes", /* 2 */
2018 "6K Bytes", /* 3 */
2019 "112K Bytes", /* 4 */
2020 "4K Bytes", /* 5 */
2021 "80K Bytes", /* 6 */
2022 "160K Bytes", /* 7 */
2023 "8K Bytes", /* 8 */
2024 "16K Bytes", /* 9 */
2025 "32K Bytes", /* 10 */
2026 "64K Bytes", /* 11 */
2027 "128K Bytes", /* 12 */
2028 "256K Bytes", /* 13 */
2029 "96K Bytes", /* 14 */
2030 "512K Bytes", /* 15 */
2031
2032 };
2033
2034 static const struct archnames { unsigned value; const char *name; } archnames[] = {
2035 { 0x19, "AT91SAM9xx Series" },
2036 { 0x29, "AT91SAM9XExx Series" },
2037 { 0x34, "AT91x34 Series" },
2038 { 0x37, "CAP7 Series" },
2039 { 0x39, "CAP9 Series" },
2040 { 0x3B, "CAP11 Series" },
2041 { 0x3C, "ATSAM4E" },
2042 { 0x40, "AT91x40 Series" },
2043 { 0x42, "AT91x42 Series" },
2044 { 0x43, "SAMG51 Series"
2045 },
2046 { 0x44, "SAMG55 Series (49-pin WLCSP)" },
2047 { 0x45, "SAMG55 Series (64-pin)" },
2048 { 0x47, "SAMG53 Series"
2049 },
2050 { 0x55, "AT91x55 Series" },
2051 { 0x60, "AT91SAM7Axx Series" },
2052 { 0x61, "AT91SAM7AQxx Series" },
2053 { 0x63, "AT91x63 Series" },
2054 { 0x64, "SAM4CxxC (100-pin version)" },
2055 { 0x66, "SAM4CxxE (144-pin version)" },
2056 { 0x70, "AT91SAM7Sxx Series" },
2057 { 0x71, "AT91SAM7XCxx Series" },
2058 { 0x72, "AT91SAM7SExx Series" },
2059 { 0x73, "AT91SAM7Lxx Series" },
2060 { 0x75, "AT91SAM7Xxx Series" },
2061 { 0x76, "AT91SAM7SLxx Series" },
2062 { 0x80, "ATSAM3UxC Series (100-pin version)" },
2063 { 0x81, "ATSAM3UxE Series (144-pin version)" },
2064 { 0x83, "ATSAM3A/SAM4A xC Series (100-pin version)"},
2065 { 0x84, "ATSAM3X/SAM4X xC Series (100-pin version)"},
2066 { 0x85, "ATSAM3X/SAM4X xE Series (144-pin version)"},
2067 { 0x86, "ATSAM3X/SAM4X xG Series (208/217-pin version)" },
2068 { 0x88, "ATSAM3S/SAM4S xA Series (48-pin version)" },
2069 { 0x89, "ATSAM3S/SAM4S xB Series (64-pin version)" },
2070 { 0x8A, "ATSAM3S/SAM4S xC Series (100-pin version)"},
2071 { 0x92, "AT91x92 Series" },
2072 { 0x93, "ATSAM3NxA Series (48-pin version)" },
2073 { 0x94, "ATSAM3NxB Series (64-pin version)" },
2074 { 0x95, "ATSAM3NxC Series (100-pin version)" },
2075 { 0x98, "ATSAM3SDxA Series (48-pin version)" },
2076 { 0x99, "ATSAM3SDxB Series (64-pin version)" },
2077 { 0x9A, "ATSAM3SDxC Series (100-pin version)" },
2078 { 0xA5, "ATSAM5A" },
2079 { 0xF0, "AT75Cxx Series" },
2080 { -1, NULL },
2081 };
2082
2083 static const char *const nvptype[] = {
2084 "rom", /* 0 */
2085 "romless or onchip flash", /* 1 */
2086 "embedded flash memory",/* 2 */
2087 "rom(nvpsiz) + embedded flash (nvpsiz2)", /* 3 */
2088 "sram emulating flash", /* 4 */
2089 _unknown, /* 5 */
2090 _unknown, /* 6 */
2091 _unknown, /* 7 */
2092 };
2093
2094 static const char *_yes_or_no(uint32_t v)
2095 {
2096 if (v)
2097 return "YES";
2098 else
2099 return "NO";
2100 }
2101
2102 static const char *const _rc_freq[] = {
2103 "4 MHz", "8 MHz", "12 MHz", "reserved"
2104 };
2105
2106 static void sam4_explain_ckgr_mor(struct sam4_chip *pChip)
2107 {
2108 uint32_t v;
2109 uint32_t rcen;
2110
2111 v = sam4_reg_fieldname(pChip, "MOSCXTEN", pChip->cfg.CKGR_MOR, 0, 1);
2112 LOG_USER("(main xtal enabled: %s)", _yes_or_no(v));
2113 v = sam4_reg_fieldname(pChip, "MOSCXTBY", pChip->cfg.CKGR_MOR, 1, 1);
2114 LOG_USER("(main osc bypass: %s)", _yes_or_no(v));
2115 rcen = sam4_reg_fieldname(pChip, "MOSCRCEN", pChip->cfg.CKGR_MOR, 3, 1);
2116 LOG_USER("(onchip RC-OSC enabled: %s)", _yes_or_no(rcen));
2117 v = sam4_reg_fieldname(pChip, "MOSCRCF", pChip->cfg.CKGR_MOR, 4, 3);
2118 LOG_USER("(onchip RC-OSC freq: %s)", _rc_freq[v]);
2119
2120 pChip->cfg.rc_freq = 0;
2121 if (rcen) {
2122 switch (v) {
2123 default:
2124 pChip->cfg.rc_freq = 0;
2125 break;
2126 case 0:
2127 pChip->cfg.rc_freq = 4 * 1000 * 1000;
2128 break;
2129 case 1:
2130 pChip->cfg.rc_freq = 8 * 1000 * 1000;
2131 break;
2132 case 2:
2133 pChip->cfg.rc_freq = 12 * 1000 * 1000;
2134 break;
2135 }
2136 }
2137
2138 v = sam4_reg_fieldname(pChip, "MOSCXTST", pChip->cfg.CKGR_MOR, 8, 8);
2139 LOG_USER("(startup clks, time= %f uSecs)",
2140 ((float)(v * 1000000)) / ((float)(pChip->cfg.slow_freq)));
2141 v = sam4_reg_fieldname(pChip, "MOSCSEL", pChip->cfg.CKGR_MOR, 24, 1);
2142 LOG_USER("(mainosc source: %s)",
2143 v ? "external xtal" : "internal RC");
2144
2145 v = sam4_reg_fieldname(pChip, "CFDEN", pChip->cfg.CKGR_MOR, 25, 1);
2146 LOG_USER("(clock failure enabled: %s)",
2147 _yes_or_no(v));
2148 }
2149
2150 static void sam4_explain_chipid_cidr(struct sam4_chip *pChip)
2151 {
2152 int x;
2153 uint32_t v;
2154 const char *cp;
2155
2156 sam4_reg_fieldname(pChip, "Version", pChip->cfg.CHIPID_CIDR, 0, 5);
2157 LOG_USER_N("\n");
2158
2159 v = sam4_reg_fieldname(pChip, "EPROC", pChip->cfg.CHIPID_CIDR, 5, 3);
2160 LOG_USER("%s", eproc_names[v]);
2161
2162 v = sam4_reg_fieldname(pChip, "NVPSIZE", pChip->cfg.CHIPID_CIDR, 8, 4);
2163 LOG_USER("%s", nvpsize[v]);
2164
2165 v = sam4_reg_fieldname(pChip, "NVPSIZE2", pChip->cfg.CHIPID_CIDR, 12, 4);
2166 LOG_USER("%s", nvpsize2[v]);
2167
2168 v = sam4_reg_fieldname(pChip, "SRAMSIZE", pChip->cfg.CHIPID_CIDR, 16, 4);
2169 LOG_USER("%s", sramsize[v]);
2170
2171 v = sam4_reg_fieldname(pChip, "ARCH", pChip->cfg.CHIPID_CIDR, 20, 8);
2172 cp = _unknown;
2173 for (x = 0; archnames[x].name; x++) {
2174 if (v == archnames[x].value) {
2175 cp = archnames[x].name;
2176 break;
2177 }
2178 }
2179
2180 LOG_USER("%s", cp);
2181
2182 v = sam4_reg_fieldname(pChip, "NVPTYP", pChip->cfg.CHIPID_CIDR, 28, 3);
2183 LOG_USER("%s", nvptype[v]);
2184
2185 v = sam4_reg_fieldname(pChip, "EXTID", pChip->cfg.CHIPID_CIDR, 31, 1);
2186 LOG_USER("(exists: %s)", _yes_or_no(v));
2187 }
2188
2189 static void sam4_explain_ckgr_mcfr(struct sam4_chip *pChip)
2190 {
2191 uint32_t v;
2192
2193 v = sam4_reg_fieldname(pChip, "MAINFRDY", pChip->cfg.CKGR_MCFR, 16, 1);
2194 LOG_USER("(main ready: %s)", _yes_or_no(v));
2195
2196 v = sam4_reg_fieldname(pChip, "MAINF", pChip->cfg.CKGR_MCFR, 0, 16);
2197
2198 v = (v * pChip->cfg.slow_freq) / 16;
2199 pChip->cfg.mainosc_freq = v;
2200
2201 LOG_USER("(%3.03f Mhz (%" PRIu32 ".%03" PRIu32 "khz slowclk)",
2202 _tomhz(v),
2203 (uint32_t)(pChip->cfg.slow_freq / 1000),
2204 (uint32_t)(pChip->cfg.slow_freq % 1000));
2205 }
2206
2207 static void sam4_explain_ckgr_plla(struct sam4_chip *pChip)
2208 {
2209 uint32_t mula, diva;
2210
2211 diva = sam4_reg_fieldname(pChip, "DIVA", pChip->cfg.CKGR_PLLAR, 0, 8);
2212 LOG_USER_N("\n");
2213 mula = sam4_reg_fieldname(pChip, "MULA", pChip->cfg.CKGR_PLLAR, 16, 11);
2214 LOG_USER_N("\n");
2215 pChip->cfg.plla_freq = 0;
2216 if (mula == 0)
2217 LOG_USER("\tPLLA Freq: (Disabled,mula = 0)");
2218 else if (diva == 0)
2219 LOG_USER("\tPLLA Freq: (Disabled,diva = 0)");
2220 else if (diva >= 1) {
2221 pChip->cfg.plla_freq = (pChip->cfg.mainosc_freq * (mula + 1) / diva);
2222 LOG_USER("\tPLLA Freq: %3.03f MHz",
2223 _tomhz(pChip->cfg.plla_freq));
2224 }
2225 }
2226
2227 static void sam4_explain_mckr(struct sam4_chip *pChip)
2228 {
2229 uint32_t css, pres, fin = 0;
2230 int pdiv = 0;
2231 const char *cp = NULL;
2232
2233 css = sam4_reg_fieldname(pChip, "CSS", pChip->cfg.PMC_MCKR, 0, 2);
2234 switch (css & 3) {
2235 case 0:
2236 fin = pChip->cfg.slow_freq;
2237 cp = "slowclk";
2238 break;
2239 case 1:
2240 fin = pChip->cfg.mainosc_freq;
2241 cp = "mainosc";
2242 break;
2243 case 2:
2244 fin = pChip->cfg.plla_freq;
2245 cp = "plla";
2246 break;
2247 case 3:
2248 if (pChip->cfg.CKGR_UCKR & (1 << 16)) {
2249 fin = 480 * 1000 * 1000;
2250 cp = "upll";
2251 } else {
2252 fin = 0;
2253 cp = "upll (*ERROR* UPLL is disabled)";
2254 }
2255 break;
2256 default:
2257 assert(0);
2258 break;
2259 }
2260
2261 LOG_USER("%s (%3.03f Mhz)",
2262 cp,
2263 _tomhz(fin));
2264 pres = sam4_reg_fieldname(pChip, "PRES", pChip->cfg.PMC_MCKR, 4, 3);
2265 switch (pres & 0x07) {
2266 case 0:
2267 pdiv = 1;
2268 cp = "selected clock";
2269 break;
2270 case 1:
2271 pdiv = 2;
2272 cp = "clock/2";
2273 break;
2274 case 2:
2275 pdiv = 4;
2276 cp = "clock/4";
2277 break;
2278 case 3:
2279 pdiv = 8;
2280 cp = "clock/8";
2281 break;
2282 case 4:
2283 pdiv = 16;
2284 cp = "clock/16";
2285 break;
2286 case 5:
2287 pdiv = 32;
2288 cp = "clock/32";
2289 break;
2290 case 6:
2291 pdiv = 64;
2292 cp = "clock/64";
2293 break;
2294 case 7:
2295 pdiv = 6;
2296 cp = "clock/6";
2297 break;
2298 default:
2299 assert(0);
2300 break;
2301 }
2302 LOG_USER("(%s)", cp);
2303 fin = fin / pdiv;
2304 /* sam4 has a *SINGLE* clock - */
2305 /* other at91 series parts have divisors for these. */
2306 pChip->cfg.cpu_freq = fin;
2307 pChip->cfg.mclk_freq = fin;
2308 pChip->cfg.fclk_freq = fin;
2309 LOG_USER("\t\tResult CPU Freq: %3.03f",
2310 _tomhz(fin));
2311 }
2312
2313 #if 0
2314 static struct sam4_chip *target2sam4(struct target *pTarget)
2315 {
2316 struct sam4_chip *pChip;
2317
2318 if (pTarget == NULL)
2319 return NULL;
2320
2321 pChip = all_sam4_chips;
2322 while (pChip) {
2323 if (pChip->target == pTarget)
2324 break; /* return below */
2325 else
2326 pChip = pChip->next;
2327 }
2328 return pChip;
2329 }
2330 #endif
2331
2332 static uint32_t *sam4_get_reg_ptr(struct sam4_cfg *pCfg, const struct sam4_reg_list *pList)
2333 {
2334 /* this function exists to help */
2335 /* keep funky offsetof() errors */
2336 /* and casting from causing bugs */
2337
2338 /* By using prototypes - we can detect what would */
2339 /* be casting errors. */
2340
2341 return (uint32_t *)(void *)(((char *)(pCfg)) + pList->struct_offset);
2342 }
2343
2344
2345 #define SAM4_ENTRY(NAME, FUNC) { .address = SAM4_ ## NAME, .struct_offset = offsetof( \
2346 struct sam4_cfg, \
2347 NAME), # NAME, FUNC }
2348 static const struct sam4_reg_list sam4_all_regs[] = {
2349 SAM4_ENTRY(CKGR_MOR, sam4_explain_ckgr_mor),
2350 SAM4_ENTRY(CKGR_MCFR, sam4_explain_ckgr_mcfr),
2351 SAM4_ENTRY(CKGR_PLLAR, sam4_explain_ckgr_plla),
2352 SAM4_ENTRY(CKGR_UCKR, NULL),
2353 SAM4_ENTRY(PMC_FSMR, NULL),
2354 SAM4_ENTRY(PMC_FSPR, NULL),
2355 SAM4_ENTRY(PMC_IMR, NULL),
2356 SAM4_ENTRY(PMC_MCKR, sam4_explain_mckr),
2357 SAM4_ENTRY(PMC_PCK0, NULL),
2358 SAM4_ENTRY(PMC_PCK1, NULL),
2359 SAM4_ENTRY(PMC_PCK2, NULL),
2360 SAM4_ENTRY(PMC_PCSR, NULL),
2361 SAM4_ENTRY(PMC_SCSR, NULL),
2362 SAM4_ENTRY(PMC_SR, NULL),
2363 SAM4_ENTRY(CHIPID_CIDR, sam4_explain_chipid_cidr),
2364 SAM4_ENTRY(CHIPID_EXID, NULL),
2365 /* TERMINATE THE LIST */
2366 { .name = NULL }
2367 };
2368 #undef SAM4_ENTRY
2369
2370 static struct sam4_bank_private *get_sam4_bank_private(struct flash_bank *bank)
2371 {
2372 return bank->driver_priv;
2373 }
2374
2375 /**
2376 * Given a pointer to where it goes in the structure,
2377 * determine the register name, address from the all registers table.
2378 */
2379 static const struct sam4_reg_list *sam4_GetReg(struct sam4_chip *pChip, uint32_t *goes_here)
2380 {
2381 const struct sam4_reg_list *pReg;
2382
2383 pReg = &(sam4_all_regs[0]);
2384 while (pReg->name) {
2385 uint32_t *pPossible;
2386
2387 /* calculate where this one go.. */
2388 /* it is "possibly" this register. */
2389
2390 pPossible = ((uint32_t *)(void *)(((char *)(&(pChip->cfg))) + pReg->struct_offset));
2391
2392 /* well? Is it this register */
2393 if (pPossible == goes_here) {
2394 /* Jump for joy! */
2395 return pReg;
2396 }
2397
2398 /* next... */
2399 pReg++;
2400 }
2401 /* This is *TOTAL*PANIC* - we are totally screwed. */
2402 LOG_ERROR("INVALID SAM4 REGISTER");
2403 return NULL;
2404 }
2405
2406 static int sam4_ReadThisReg(struct sam4_chip *pChip, uint32_t *goes_here)
2407 {
2408 const struct sam4_reg_list *pReg;
2409 int r;
2410
2411 pReg = sam4_GetReg(pChip, goes_here);
2412 if (!pReg)
2413 return ERROR_FAIL;
2414
2415 r = target_read_u32(pChip->target, pReg->address, goes_here);
2416 if (r != ERROR_OK) {
2417 LOG_ERROR("Cannot read SAM4 register: %s @ 0x%08x, Err: %d",
2418 pReg->name, (unsigned)(pReg->address), r);
2419 }
2420 return r;
2421 }
2422
2423 static int sam4_ReadAllRegs(struct sam4_chip *pChip)
2424 {
2425 int r;
2426 const struct sam4_reg_list *pReg;
2427
2428 pReg = &(sam4_all_regs[0]);
2429 while (pReg->name) {
2430 r = sam4_ReadThisReg(pChip,
2431 sam4_get_reg_ptr(&(pChip->cfg), pReg));
2432 if (r != ERROR_OK) {
2433 LOG_ERROR("Cannot read SAM4 register: %s @ 0x%08x, Error: %d",
2434 pReg->name, ((unsigned)(pReg->address)), r);
2435 return r;
2436 }
2437 pReg++;
2438 }
2439
2440 return ERROR_OK;
2441 }
2442
2443 static int sam4_GetInfo(struct sam4_chip *pChip)
2444 {
2445 const struct sam4_reg_list *pReg;
2446 uint32_t regval;
2447 int r;
2448
2449 r = sam4_ReadAllRegs(pChip);
2450 if (r != ERROR_OK)
2451 return r;
2452
2453 pReg = &(sam4_all_regs[0]);
2454 while (pReg->name) {
2455 /* display all regs */
2456 LOG_DEBUG("Start: %s", pReg->name);
2457 regval = *sam4_get_reg_ptr(&(pChip->cfg), pReg);
2458 LOG_USER("%*s: [0x%08" PRIx32 "] -> 0x%08" PRIx32,
2459 REG_NAME_WIDTH,
2460 pReg->name,
2461 pReg->address,
2462 regval);
2463 if (pReg->explain_func)
2464 (*(pReg->explain_func))(pChip);
2465 LOG_DEBUG("End: %s", pReg->name);
2466 pReg++;
2467 }
2468 LOG_USER(" rc-osc: %3.03f MHz", _tomhz(pChip->cfg.rc_freq));
2469 LOG_USER(" mainosc: %3.03f MHz", _tomhz(pChip->cfg.mainosc_freq));
2470 LOG_USER(" plla: %3.03f MHz", _tomhz(pChip->cfg.plla_freq));
2471 LOG_USER(" cpu-freq: %3.03f MHz", _tomhz(pChip->cfg.cpu_freq));
2472 LOG_USER("mclk-freq: %3.03f MHz", _tomhz(pChip->cfg.mclk_freq));
2473
2474 LOG_USER(" UniqueId: 0x%08" PRIx32 " 0x%08" PRIx32 " 0x%08" PRIx32 " 0x%08"PRIx32,
2475 pChip->cfg.unique_id[0],
2476 pChip->cfg.unique_id[1],
2477 pChip->cfg.unique_id[2],
2478 pChip->cfg.unique_id[3]);
2479
2480 return ERROR_OK;
2481 }
2482
2483 static int sam4_protect_check(struct flash_bank *bank)
2484 {
2485 int r;
2486 uint32_t v[4] = {0};
2487 unsigned x;
2488 struct sam4_bank_private *pPrivate;
2489
2490 LOG_DEBUG("Begin");
2491 if (bank->target->state != TARGET_HALTED) {
2492 LOG_ERROR("Target not halted");
2493 return ERROR_TARGET_NOT_HALTED;
2494 }
2495
2496 pPrivate = get_sam4_bank_private(bank);
2497 if (!pPrivate) {
2498 LOG_ERROR("no private for this bank?");
2499 return ERROR_FAIL;
2500 }
2501 if (!(pPrivate->probed))
2502 return ERROR_FLASH_BANK_NOT_PROBED;
2503
2504 r = FLASHD_GetLockBits(pPrivate, v);
2505 if (r != ERROR_OK) {
2506 LOG_DEBUG("Failed: %d", r);
2507 return r;
2508 }
2509
2510 for (x = 0; x < pPrivate->nsectors; x++)
2511 bank->sectors[x].is_protected = (!!(v[x >> 5] & (1 << (x % 32))));
2512 LOG_DEBUG("Done");
2513 return ERROR_OK;
2514 }
2515
2516 FLASH_BANK_COMMAND_HANDLER(sam4_flash_bank_command)
2517 {
2518 struct sam4_chip *pChip;
2519
2520 pChip = all_sam4_chips;
2521
2522 /* is this an existing chip? */
2523 while (pChip) {
2524 if (pChip->target == bank->target)
2525 break;
2526 pChip = pChip->next;
2527 }
2528
2529 if (!pChip) {
2530 /* this is a *NEW* chip */
2531 pChip = calloc(1, sizeof(struct sam4_chip));
2532 if (!pChip) {
2533 LOG_ERROR("NO RAM!");
2534 return ERROR_FAIL;
2535 }
2536 pChip->target = bank->target;
2537 /* insert at head */
2538 pChip->next = all_sam4_chips;
2539 all_sam4_chips = pChip;
2540 pChip->target = bank->target;
2541 /* assumption is this runs at 32khz */
2542 pChip->cfg.slow_freq = 32768;
2543 pChip->probed = false;
2544 }
2545
2546 switch (bank->base) {
2547 default:
2548 LOG_ERROR("Address 0x%08x invalid bank address (try 0x%08x"
2549 "[at91sam4s series] )",
2550 ((unsigned int)(bank->base)),
2551 ((unsigned int)(FLASH_BANK_BASE_S)));
2552 return ERROR_FAIL;
2553
2554 /* at91sam4s series only has bank 0*/
2555 /* at91sam4sd series has the same address for bank 0 (FLASH_BANK0_BASE_SD)*/
2556 case FLASH_BANK_BASE_S:
2557 case FLASH_BANK_BASE_C:
2558 bank->driver_priv = &(pChip->details.bank[0]);
2559 bank->bank_number = 0;
2560 pChip->details.bank[0].pChip = pChip;
2561 pChip->details.bank[0].pBank = bank;
2562 break;
2563
2564 /* Bank 1 of at91sam4sd/at91sam4c32 series */
2565 case FLASH_BANK1_BASE_1024K_SD:
2566 case FLASH_BANK1_BASE_2048K_SD:
2567 case FLASH_BANK1_BASE_C32:
2568 bank->driver_priv = &(pChip->details.bank[1]);
2569 bank->bank_number = 1;
2570 pChip->details.bank[1].pChip = pChip;
2571 pChip->details.bank[1].pBank = bank;
2572 break;
2573 }
2574
2575 /* we initialize after probing. */
2576 return ERROR_OK;
2577 }
2578
2579 /**
2580 * Remove all chips from the internal list without distinguishing which one
2581 * is owned by this bank. This simplification works only for one shot
2582 * deallocation like current flash_free_all_banks()
2583 */
2584 static void sam4_free_driver_priv(struct flash_bank *bank)
2585 {
2586 struct sam4_chip *chip = all_sam4_chips;
2587 while (chip) {
2588 struct sam4_chip *next = chip->next;
2589 free(chip);
2590 chip = next;
2591 }
2592 all_sam4_chips = NULL;
2593 }
2594
2595 static int sam4_GetDetails(struct sam4_bank_private *pPrivate)
2596 {
2597 const struct sam4_chip_details *pDetails;
2598 struct sam4_chip *pChip;
2599 struct flash_bank *saved_banks[SAM4_MAX_FLASH_BANKS];
2600 unsigned x;
2601
2602 LOG_DEBUG("Begin");
2603 pDetails = all_sam4_details;
2604 while (pDetails->name) {
2605 /* Compare cidr without version bits */
2606 if (pDetails->chipid_cidr == (pPrivate->pChip->cfg.CHIPID_CIDR & 0xFFFFFFE0))
2607 break;
2608 else
2609 pDetails++;
2610 }
2611 if (pDetails->name == NULL) {
2612 LOG_ERROR("SAM4 ChipID 0x%08x not found in table (perhaps you can ID this chip?)",
2613 (unsigned int)(pPrivate->pChip->cfg.CHIPID_CIDR));
2614 /* Help the victim, print details about the chip */
2615 LOG_INFO("SAM4 CHIPID_CIDR: 0x%08" PRIx32 " decodes as follows",
2616 pPrivate->pChip->cfg.CHIPID_CIDR);
2617 sam4_explain_chipid_cidr(pPrivate->pChip);
2618 return ERROR_FAIL;
2619 } else {
2620 LOG_DEBUG("SAM4 Found chip %s, CIDR 0x%08" PRIx32, pDetails->name, pDetails->chipid_cidr);
2621 }
2622
2623 /* DANGER: THERE ARE DRAGONS HERE */
2624
2625 /* get our pChip - it is going */
2626 /* to be over-written shortly */
2627 pChip = pPrivate->pChip;
2628
2629 /* Note that, in reality: */
2630 /* */
2631 /* pPrivate = &(pChip->details.bank[0]) */
2632 /* or pPrivate = &(pChip->details.bank[1]) */
2633 /* */
2634
2635 /* save the "bank" pointers */
2636 for (x = 0; x < SAM4_MAX_FLASH_BANKS; x++)
2637 saved_banks[x] = pChip->details.bank[x].pBank;
2638
2639 /* Overwrite the "details" structure. */
2640 memcpy(&(pPrivate->pChip->details),
2641 pDetails,
2642 sizeof(pPrivate->pChip->details));
2643
2644 /* now fix the ghosted pointers */
2645 for (x = 0; x < SAM4_MAX_FLASH_BANKS; x++) {
2646 pChip->details.bank[x].pChip = pChip;
2647 pChip->details.bank[x].pBank = saved_banks[x];
2648 }
2649
2650 /* update the *BANK*SIZE* */
2651
2652 LOG_DEBUG("End");
2653 return ERROR_OK;
2654 }
2655
2656 static int sam4_info(struct flash_bank *bank, char *buf, int buf_size)
2657 {
2658 struct sam4_bank_private *pPrivate;
2659 int k = bank->size / 1024;
2660
2661 pPrivate = get_sam4_bank_private(bank);
2662 if (pPrivate == NULL) {
2663 buf[0] = '\0';
2664 return ERROR_FAIL;
2665 }
2666
2667 snprintf(buf, buf_size,
2668 "%s bank %d: %d kB at " TARGET_ADDR_FMT,
2669 pPrivate->pChip->details.name,
2670 pPrivate->bank_number,
2671 k,
2672 bank->base);
2673
2674 return ERROR_OK;
2675 }
2676
2677 static int sam4_probe(struct flash_bank *bank)
2678 {
2679 int r;
2680 struct sam4_bank_private *pPrivate;
2681
2682
2683 LOG_DEBUG("Begin: Bank: %u", bank->bank_number);
2684 if (bank->target->state != TARGET_HALTED) {
2685 LOG_ERROR("Target not halted");
2686 return ERROR_TARGET_NOT_HALTED;
2687 }
2688
2689 pPrivate = get_sam4_bank_private(bank);
2690 if (!pPrivate) {
2691 LOG_ERROR("Invalid/unknown bank number");
2692 return ERROR_FAIL;
2693 }
2694
2695 r = sam4_ReadAllRegs(pPrivate->pChip);
2696 if (r != ERROR_OK)
2697 return r;
2698
2699 LOG_DEBUG("Here");
2700 if (pPrivate->pChip->probed)
2701 r = sam4_GetInfo(pPrivate->pChip);
2702 else
2703 r = sam4_GetDetails(pPrivate);
2704 if (r != ERROR_OK)
2705 return r;
2706
2707 /* update the flash bank size */
2708 for (unsigned int x = 0; x < SAM4_MAX_FLASH_BANKS; x++) {
2709 if (bank->base == pPrivate->pChip->details.bank[x].base_address) {
2710 bank->size = pPrivate->pChip->details.bank[x].size_bytes;
2711 LOG_DEBUG("SAM4 Set flash bank to " TARGET_ADDR_FMT " - "
2712 TARGET_ADDR_FMT ", idx %d", bank->base,
2713 bank->base + bank->size, x);
2714 break;
2715 }
2716 }
2717
2718 if (bank->sectors == NULL) {
2719 bank->sectors = calloc(pPrivate->nsectors, (sizeof((bank->sectors)[0])));
2720 if (bank->sectors == NULL) {
2721 LOG_ERROR("No memory!");
2722 return ERROR_FAIL;
2723 }
2724 bank->num_sectors = pPrivate->nsectors;
2725
2726 for (unsigned int x = 0; x < bank->num_sectors; x++) {
2727 bank->sectors[x].size = pPrivate->sector_size;
2728 bank->sectors[x].offset = x * (pPrivate->sector_size);
2729 /* mark as unknown */
2730 bank->sectors[x].is_erased = -1;
2731 bank->sectors[x].is_protected = -1;
2732 }
2733 }
2734
2735 pPrivate->probed = true;
2736
2737 r = sam4_protect_check(bank);
2738 if (r != ERROR_OK)
2739 return r;
2740
2741 LOG_DEBUG("Bank = %d, nbanks = %d",
2742 pPrivate->bank_number, pPrivate->pChip->details.n_banks);
2743 if ((pPrivate->bank_number + 1) == pPrivate->pChip->details.n_banks) {
2744 /* read unique id, */
2745 /* it appears to be associated with the *last* flash bank. */
2746 FLASHD_ReadUniqueID(pPrivate);
2747 }
2748
2749 return r;
2750 }
2751
2752 static int sam4_auto_probe(struct flash_bank *bank)
2753 {
2754 struct sam4_bank_private *pPrivate;
2755
2756 pPrivate = get_sam4_bank_private(bank);
2757 if (pPrivate && pPrivate->probed)
2758 return ERROR_OK;
2759
2760 return sam4_probe(bank);
2761 }
2762
2763 static int sam4_erase(struct flash_bank *bank, unsigned int first,
2764 unsigned int last)
2765 {
2766 struct sam4_bank_private *pPrivate;
2767 int r;
2768 int pageCount;
2769 /*16 pages equals 8KB - Same size as a lock region*/
2770 pageCount = 16;
2771 uint32_t status;
2772
2773 LOG_DEBUG("Here");
2774 if (bank->target->state != TARGET_HALTED) {
2775 LOG_ERROR("Target not halted");
2776 return ERROR_TARGET_NOT_HALTED;
2777 }
2778
2779 r = sam4_auto_probe(bank);
2780 if (r != ERROR_OK) {
2781 LOG_DEBUG("Here,r=%d", r);
2782 return r;
2783 }
2784
2785 pPrivate = get_sam4_bank_private(bank);
2786 if (!(pPrivate->probed))
2787 return ERROR_FLASH_BANK_NOT_PROBED;
2788
2789 if ((first == 0) && ((last + 1) == pPrivate->nsectors)) {
2790 /* whole chip */
2791 LOG_DEBUG("Here");
2792 return FLASHD_EraseEntireBank(pPrivate);
2793 }
2794 LOG_INFO("sam4 does not auto-erase while programming (Erasing relevant sectors)");
2795 LOG_INFO("sam4 First: 0x%08x Last: 0x%08x", first, last);
2796 for (unsigned int i = first; i <= last; i++) {
2797 /*16 pages equals 8KB - Same size as a lock region*/
2798 r = FLASHD_ErasePages(pPrivate, (i * pageCount), pageCount, &status);
2799 LOG_INFO("Erasing sector: 0x%08x", i);
2800 if (r != ERROR_OK)
2801 LOG_ERROR("SAM4: Error performing Erase page @ lock region number %u",
2802 i);
2803 if (status & (1 << 2)) {
2804 LOG_ERROR("SAM4: Lock Region %u is locked", i);
2805 return ERROR_FAIL;
2806 }
2807 if (status & (1 << 1)) {
2808 LOG_ERROR("SAM4: Flash Command error @lock region %u", i);
2809 return ERROR_FAIL;
2810 }
2811 }
2812
2813 return ERROR_OK;
2814 }
2815
2816 static int sam4_protect(struct flash_bank *bank, int set, unsigned int first,
2817 unsigned int last)
2818 {
2819 struct sam4_bank_private *pPrivate;
2820 int r;
2821
2822 LOG_DEBUG("Here");
2823 if (bank->target->state != TARGET_HALTED) {
2824 LOG_ERROR("Target not halted");
2825 return ERROR_TARGET_NOT_HALTED;
2826 }
2827
2828 pPrivate = get_sam4_bank_private(bank);
2829 if (!(pPrivate->probed))
2830 return ERROR_FLASH_BANK_NOT_PROBED;
2831
2832 if (set)
2833 r = FLASHD_Lock(pPrivate, first, last);
2834 else
2835 r = FLASHD_Unlock(pPrivate, first, last);
2836 LOG_DEBUG("End: r=%d", r);
2837
2838 return r;
2839
2840 }
2841
2842 static int sam4_page_read(struct sam4_bank_private *pPrivate, unsigned pagenum, uint8_t *buf)
2843 {
2844 uint32_t adr;
2845 int r;
2846
2847 adr = pagenum * pPrivate->page_size;
2848 adr = adr + pPrivate->base_address;
2849
2850 r = target_read_memory(pPrivate->pChip->target,
2851 adr,
2852 4, /* THIS*MUST*BE* in 32bit values */
2853 pPrivate->page_size / 4,
2854 buf);
2855 if (r != ERROR_OK)
2856 LOG_ERROR("SAM4: Flash program failed to read page phys address: 0x%08x",
2857 (unsigned int)(adr));
2858 return r;
2859 }
2860
2861 static int sam4_set_wait(struct sam4_bank_private *pPrivate)
2862 {
2863 uint32_t fmr; /* EEFC Flash Mode Register */
2864 int r;
2865
2866 /* Get flash mode register value */
2867 r = target_read_u32(pPrivate->pChip->target, pPrivate->controller_address, &fmr);
2868 if (r != ERROR_OK) {
2869 LOG_ERROR("Error Read failed: read flash mode register");
2870 return r;
2871 }
2872
2873 /* Clear flash wait state field */
2874 fmr &= 0xfffff0ff;
2875
2876 /* set FWS (flash wait states) field in the FMR (flash mode register) */
2877 fmr |= (pPrivate->flash_wait_states << 8);
2878
2879 LOG_DEBUG("Flash Mode: 0x%08x", ((unsigned int)(fmr)));
2880 r = target_write_u32(pPrivate->pBank->target, pPrivate->controller_address, fmr);
2881 if (r != ERROR_OK)
2882 LOG_ERROR("Error Write failed: set flash mode register");
2883
2884 return r;
2885 }
2886
2887 static int sam4_page_write(struct sam4_bank_private *pPrivate, unsigned pagenum, const uint8_t *buf)
2888 {
2889 uint32_t adr;
2890 uint32_t status;
2891 int r;
2892
2893 adr = pagenum * pPrivate->page_size;
2894 adr = (adr + pPrivate->base_address);
2895
2896 /* 1st sector 8kBytes - page 0 - 15*/
2897 /* 2nd sector 8kBytes - page 16 - 30*/
2898 /* 3rd sector 48kBytes - page 31 - 127*/
2899 LOG_DEBUG("Wr Page %u @ phys address: 0x%08x", pagenum, (unsigned int)(adr));
2900 r = target_write_memory(pPrivate->pChip->target,
2901 adr,
2902 4, /* THIS*MUST*BE* in 32bit values */
2903 pPrivate->page_size / 4,
2904 buf);
2905 if (r != ERROR_OK) {
2906 LOG_ERROR("SAM4: Failed to write (buffer) page at phys address 0x%08x",
2907 (unsigned int)(adr));
2908 return r;
2909 }
2910
2911 r = EFC_PerformCommand(pPrivate,
2912 /* send Erase & Write Page */
2913 AT91C_EFC_FCMD_WP, /*AT91C_EFC_FCMD_EWP only works on first two 8kb sectors*/
2914 pagenum,
2915 &status);
2916
2917 if (r != ERROR_OK)
2918 LOG_ERROR("SAM4: Error performing Write page @ phys address 0x%08x",
2919 (unsigned int)(adr));
2920 if (status & (1 << 2)) {
2921 LOG_ERROR("SAM4: Page @ Phys address 0x%08x is locked", (unsigned int)(adr));
2922 return ERROR_FAIL;
2923 }
2924 if (status & (1 << 1)) {
2925 LOG_ERROR("SAM4: Flash Command error @phys address 0x%08x", (unsigned int)(adr));
2926 return ERROR_FAIL;
2927 }
2928 return ERROR_OK;
2929 }
2930
2931 static int sam4_write(struct flash_bank *bank,
2932 const uint8_t *buffer,
2933 uint32_t offset,
2934 uint32_t count)
2935 {
2936 int n;
2937 unsigned page_cur;
2938 unsigned page_end;
2939 int r;
2940 unsigned page_offset;
2941 struct sam4_bank_private *pPrivate;
2942 uint8_t *pagebuffer;
2943
2944 /* in case we bail further below, set this to null */
2945 pagebuffer = NULL;
2946
2947 /* ignore dumb requests */
2948 if (count == 0) {
2949 r = ERROR_OK;
2950 goto done;
2951 }
2952
2953 if (bank->target->state != TARGET_HALTED) {
2954 LOG_ERROR("Target not halted");
2955 r = ERROR_TARGET_NOT_HALTED;
2956 goto done;
2957 }
2958
2959 pPrivate = get_sam4_bank_private(bank);
2960 if (!(pPrivate->probed)) {
2961 r = ERROR_FLASH_BANK_NOT_PROBED;
2962 goto done;
2963 }
2964
2965 if ((offset + count) > pPrivate->size_bytes) {
2966 LOG_ERROR("Flash write error - past end of bank");
2967 LOG_ERROR(" offset: 0x%08x, count 0x%08x, BankEnd: 0x%08x",
2968 (unsigned int)(offset),
2969 (unsigned int)(count),
2970 (unsigned int)(pPrivate->size_bytes));
2971 r = ERROR_FAIL;
2972 goto done;
2973 }
2974
2975 pagebuffer = malloc(pPrivate->page_size);
2976 if (!pagebuffer) {
2977 LOG_ERROR("No memory for %d Byte page buffer", (int)(pPrivate->page_size));
2978 r = ERROR_FAIL;
2979 goto done;
2980 }
2981
2982 r = sam4_set_wait(pPrivate);
2983 if (r != ERROR_OK)
2984 goto done;
2985
2986 /* what page do we start & end in? */
2987 page_cur = offset / pPrivate->page_size;
2988 page_end = (offset + count - 1) / pPrivate->page_size;
2989
2990 LOG_DEBUG("Offset: 0x%08x, Count: 0x%08x", (unsigned int)(offset), (unsigned int)(count));
2991 LOG_DEBUG("Page start: %d, Page End: %d", (int)(page_cur), (int)(page_end));
2992
2993 /* Special case: all one page */
2994 /* */
2995 /* Otherwise: */
2996 /* (1) non-aligned start */
2997 /* (2) body pages */
2998 /* (3) non-aligned end. */
2999
3000 /* Handle special case - all one page. */
3001 if (page_cur == page_end) {
3002 LOG_DEBUG("Special case, all in one page");
3003 r = sam4_page_read(pPrivate, page_cur, pagebuffer);
3004 if (r != ERROR_OK)
3005 goto done;
3006
3007 page_offset = (offset & (pPrivate->page_size-1));
3008 memcpy(pagebuffer + page_offset,
3009 buffer,
3010 count);
3011
3012 r = sam4_page_write(pPrivate, page_cur, pagebuffer);
3013 if (r != ERROR_OK)
3014 goto done;
3015 r = ERROR_OK;
3016 goto done;
3017 }
3018
3019 /* non-aligned start */
3020 page_offset = offset & (pPrivate->page_size - 1);
3021 if (page_offset) {
3022 LOG_DEBUG("Not-Aligned start");
3023 /* read the partial */
3024 r = sam4_page_read(pPrivate, page_cur, pagebuffer);
3025 if (r != ERROR_OK)
3026 goto done;
3027
3028 /* over-write with new data */
3029 n = (pPrivate->page_size - page_offset);
3030 memcpy(pagebuffer + page_offset,
3031 buffer,
3032 n);
3033
3034 r = sam4_page_write(pPrivate, page_cur, pagebuffer);
3035 if (r != ERROR_OK)
3036 goto done;
3037
3038 count -= n;
3039 offset += n;
3040 buffer += n;
3041 page_cur++;
3042 }
3043
3044 /* By checking that offset is correct here, we also
3045 fix a clang warning */
3046 assert(offset % pPrivate->page_size == 0);
3047
3048 /* intermediate large pages */
3049 /* also - the final *terminal* */
3050 /* if that terminal page is a full page */
3051 LOG_DEBUG("Full Page Loop: cur=%d, end=%d, count = 0x%08x",
3052 (int)page_cur, (int)page_end, (unsigned int)(count));
3053
3054 while ((page_cur < page_end) &&
3055 (count >= pPrivate->page_size)) {
3056 r = sam4_page_write(pPrivate, page_cur, buffer);
3057 if (r != ERROR_OK)
3058 goto done;
3059 count -= pPrivate->page_size;
3060 buffer += pPrivate->page_size;
3061 page_cur += 1;
3062 }
3063
3064 /* terminal partial page? */
3065 if (count) {
3066 LOG_DEBUG("Terminal partial page, count = 0x%08x", (unsigned int)(count));
3067 /* we have a partial page */
3068 r = sam4_page_read(pPrivate, page_cur, pagebuffer);
3069 if (r != ERROR_OK)
3070 goto done;
3071 /* data goes at start */
3072 memcpy(pagebuffer, buffer, count);
3073 r = sam4_page_write(pPrivate, page_cur, pagebuffer);
3074 if (r != ERROR_OK)
3075 goto done;
3076 }
3077 LOG_DEBUG("Done!");
3078 r = ERROR_OK;
3079 done:
3080 free(pagebuffer);
3081 return r;
3082 }
3083
3084 COMMAND_HANDLER(sam4_handle_info_command)
3085 {
3086 struct sam4_chip *pChip;
3087 pChip = get_current_sam4(CMD);
3088 if (!pChip)
3089 return ERROR_OK;
3090
3091 unsigned x;
3092 int r;
3093
3094 /* bank0 must exist before we can do anything */
3095 if (pChip->details.bank[0].pBank == NULL) {
3096 x = 0;
3097 need_define:
3098 command_print(CMD,
3099 "Please define bank %d via command: flash bank %s ... ",
3100 x,
3101 at91sam4_flash.name);
3102 return ERROR_FAIL;
3103 }
3104
3105 /* if bank 0 is not probed, then probe it */
3106 if (!(pChip->details.bank[0].probed)) {
3107 r = sam4_auto_probe(pChip->details.bank[0].pBank);
3108 if (r != ERROR_OK)
3109 return ERROR_FAIL;
3110 }
3111 /* above guarantees the "chip details" structure is valid */
3112 /* and thus, bank private areas are valid */
3113 /* and we have a SAM4 chip, what a concept! */
3114
3115 /* auto-probe other banks, 0 done above */
3116 for (x = 1; x < SAM4_MAX_FLASH_BANKS; x++) {
3117 /* skip banks not present */
3118 if (!(pChip->details.bank[x].present))
3119 continue;
3120
3121 if (pChip->details.bank[x].pBank == NULL)
3122 goto need_define;
3123
3124 if (pChip->details.bank[x].probed)
3125 continue;
3126
3127 r = sam4_auto_probe(pChip->details.bank[x].pBank);
3128 if (r != ERROR_OK)
3129 return r;
3130 }
3131
3132 r = sam4_GetInfo(pChip);
3133 if (r != ERROR_OK) {
3134 LOG_DEBUG("Sam4Info, Failed %d", r);
3135 return r;
3136 }
3137
3138 return ERROR_OK;
3139 }
3140
3141 COMMAND_HANDLER(sam4_handle_gpnvm_command)
3142 {
3143 unsigned x, v;
3144 int r, who;
3145 struct sam4_chip *pChip;
3146
3147 pChip = get_current_sam4(CMD);
3148 if (!pChip)
3149 return ERROR_OK;
3150
3151 if (pChip->target->state != TARGET_HALTED) {
3152 LOG_ERROR("sam4 - target not halted");
3153 return ERROR_TARGET_NOT_HALTED;
3154 }
3155
3156 if (pChip->details.bank[0].pBank == NULL) {
3157 command_print(CMD, "Bank0 must be defined first via: flash bank %s ...",
3158 at91sam4_flash.name);
3159 return ERROR_FAIL;
3160 }
3161 if (!pChip->details.bank[0].probed) {
3162 r = sam4_auto_probe(pChip->details.bank[0].pBank);
3163 if (r != ERROR_OK)
3164 return r;
3165 }
3166
3167 switch (CMD_ARGC) {
3168 default:
3169 return ERROR_COMMAND_SYNTAX_ERROR;
3170 case 0:
3171 goto showall;
3172 case 1:
3173 who = -1;
3174 break;
3175 case 2:
3176 if ((0 == strcmp(CMD_ARGV[0], "show")) && (0 == strcmp(CMD_ARGV[1], "all")))
3177 who = -1;
3178 else {
3179 uint32_t v32;
3180 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], v32);
3181 who = v32;
3182 }
3183 break;
3184 }
3185
3186 if (0 == strcmp("show", CMD_ARGV[0])) {
3187 if (who == -1) {
3188 showall:
3189 r = ERROR_OK;
3190 for (x = 0; x < pChip->details.n_gpnvms; x++) {
3191 r = FLASHD_GetGPNVM(&(pChip->details.bank[0]), x, &v);
3192 if (r != ERROR_OK)
3193 break;
3194 command_print(CMD, "sam4-gpnvm%u: %u", x, v);
3195 }
3196 return r;
3197 }
3198 if ((who >= 0) && (((unsigned)(who)) < pChip->details.n_gpnvms)) {
3199 r = FLASHD_GetGPNVM(&(pChip->details.bank[0]), who, &v);
3200 if (r == ERROR_OK)
3201 command_print(CMD, "sam4-gpnvm%u: %u", who, v);
3202 return r;
3203 } else {
3204 command_print(CMD, "sam4-gpnvm invalid GPNVM: %u", who);
3205 return ERROR_COMMAND_SYNTAX_ERROR;
3206 }
3207 }
3208
3209 if (who == -1) {
3210 command_print(CMD, "Missing GPNVM number");
3211 return ERROR_COMMAND_SYNTAX_ERROR;
3212 }
3213
3214 if (0 == strcmp("set", CMD_ARGV[0]))
3215 r = FLASHD_SetGPNVM(&(pChip->details.bank[0]), who);
3216 else if ((0 == strcmp("clr", CMD_ARGV[0])) ||
3217 (0 == strcmp("clear", CMD_ARGV[0]))) /* quietly accept both */
3218 r = FLASHD_ClrGPNVM(&(pChip->details.bank[0]), who);
3219 else {
3220 command_print(CMD, "Unknown command: %s", CMD_ARGV[0]);
3221 r = ERROR_COMMAND_SYNTAX_ERROR;
3222 }
3223 return r;
3224 }
3225
3226 COMMAND_HANDLER(sam4_handle_slowclk_command)
3227 {
3228 struct sam4_chip *pChip;
3229
3230 pChip = get_current_sam4(CMD);
3231 if (!pChip)
3232 return ERROR_OK;
3233
3234 switch (CMD_ARGC) {
3235 case 0:
3236 /* show */
3237 break;
3238 case 1:
3239 {
3240 /* set */
3241 uint32_t v;
3242 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], v);
3243 if (v > 200000) {
3244 /* absurd slow clock of 200Khz? */
3245 command_print(CMD, "Absurd/illegal slow clock freq: %d\n", (int)(v));
3246 return ERROR_COMMAND_SYNTAX_ERROR;
3247 }
3248 pChip->cfg.slow_freq = v;
3249 break;
3250 }
3251 default:
3252 /* error */
3253 command_print(CMD, "Too many parameters");
3254 return ERROR_COMMAND_SYNTAX_ERROR;
3255 }
3256 command_print(CMD, "Slowclk freq: %d.%03dkhz",
3257 (int)(pChip->cfg.slow_freq / 1000),
3258 (int)(pChip->cfg.slow_freq % 1000));
3259 return ERROR_OK;
3260 }
3261
3262 static const struct command_registration at91sam4_exec_command_handlers[] = {
3263 {
3264 .name = "gpnvm",
3265 .handler = sam4_handle_gpnvm_command,
3266 .mode = COMMAND_EXEC,
3267 .usage = "[('clr'|'set'|'show') bitnum]",
3268 .help = "Without arguments, shows all bits in the gpnvm "
3269 "register. Otherwise, clears, sets, or shows one "
3270 "General Purpose Non-Volatile Memory (gpnvm) bit.",
3271 },
3272 {
3273 .name = "info",
3274 .handler = sam4_handle_info_command,
3275 .mode = COMMAND_EXEC,
3276 .help = "Print information about the current at91sam4 chip "
3277 "and its flash configuration.",
3278 .usage = "",
3279 },
3280 {
3281 .name = "slowclk",
3282 .handler = sam4_handle_slowclk_command,
3283 .mode = COMMAND_EXEC,
3284 .usage = "[clock_hz]",
3285 .help = "Display or set the slowclock frequency "
3286 "(default 32768 Hz).",
3287 },
3288 COMMAND_REGISTRATION_DONE
3289 };
3290 static const struct command_registration at91sam4_command_handlers[] = {
3291 {
3292 .name = "at91sam4",
3293 .mode = COMMAND_ANY,
3294 .help = "at91sam4 flash command group",
3295 .usage = "",
3296 .chain = at91sam4_exec_command_handlers,
3297 },
3298 COMMAND_REGISTRATION_DONE
3299 };
3300
3301 const struct flash_driver at91sam4_flash = {
3302 .name = "at91sam4",
3303 .commands = at91sam4_command_handlers,
3304 .flash_bank_command = sam4_flash_bank_command,
3305 .erase = sam4_erase,
3306 .protect = sam4_protect,
3307 .write = sam4_write,
3308 .read = default_flash_read,
3309 .probe = sam4_probe,
3310 .auto_probe = sam4_auto_probe,
3311 .erase_check = default_flash_blank_check,
3312 .protect_check = sam4_protect_check,
3313 .info = sam4_info,
3314 .free_driver_priv = sam4_free_driver_priv,
3315 };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)