]> git.sur5r.net Git - openocd/blob - src/flash/nor/at91sam4.c
50aa98b8935438186eda1ab4b9bf6d2340bcc653
[openocd] / 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 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 series (has always one flash bank)*/
69 #define FLASH_BANK_BASE_S   0x00400000
70
71 /* at91sam4sd series (two one flash banks), first bank address */
72 #define FLASH_BANK0_BASE_SD FLASH_BANK_BASE_S
73 /* at91sam4sd16x, second bank address */
74 #define FLASH_BANK1_BASE_1024K_SD (FLASH_BANK0_BASE_SD+(1024*1024/2))
75 /* at91sam4sd32x, second bank address */
76 #define FLASH_BANK1_BASE_2048K_SD (FLASH_BANK0_BASE_SD+(2048*1024/2))
77
78 #define         AT91C_EFC_FCMD_GETD                 (0x0)       /* (EFC) Get Flash Descriptor */
79 #define         AT91C_EFC_FCMD_WP                   (0x1)       /* (EFC) Write Page */
80 #define         AT91C_EFC_FCMD_WPL                  (0x2)       /* (EFC) Write Page and Lock */
81 #define         AT91C_EFC_FCMD_EWP                  (0x3)       /* (EFC) Erase Page and Write Page */
82 #define         AT91C_EFC_FCMD_EWPL                 (0x4)       /* (EFC) Erase Page and Write Page then Lock */
83 #define         AT91C_EFC_FCMD_EA                   (0x5)       /* (EFC) Erase All */
84 /* cmd6 is not present in the at91sam4u4/2/1 data sheet table 19-2 */
85 /* #define      AT91C_EFC_FCMD_EPL                  (0x6) // (EFC) Erase plane? */
86 #define                 AT91C_EFC_FCMD_EPA                  (0x7)     /* (EFC) Erase pages */
87 #define         AT91C_EFC_FCMD_SLB                  (0x8)       /* (EFC) Set Lock Bit */
88 #define         AT91C_EFC_FCMD_CLB                  (0x9)       /* (EFC) Clear Lock Bit */
89 #define         AT91C_EFC_FCMD_GLB                  (0xA)       /* (EFC) Get Lock Bit */
90 #define         AT91C_EFC_FCMD_SFB                  (0xB)       /* (EFC) Set Fuse Bit */
91 #define         AT91C_EFC_FCMD_CFB                  (0xC)       /* (EFC) Clear Fuse Bit */
92 #define         AT91C_EFC_FCMD_GFB                  (0xD)       /* (EFC) Get Fuse Bit */
93 #define         AT91C_EFC_FCMD_STUI                 (0xE)       /* (EFC) Start Read Unique ID */
94 #define         AT91C_EFC_FCMD_SPUI                 (0xF)       /* (EFC) Stop Read Unique ID */
95
96 #define  offset_EFC_FMR   0
97 #define  offset_EFC_FCR   4
98 #define  offset_EFC_FSR   8
99 #define  offset_EFC_FRR   12
100
101 extern struct flash_driver at91sam4_flash;
102
103 static float _tomhz(uint32_t freq_hz)
104 {
105         float f;
106
107         f = ((float)(freq_hz)) / 1000000.0;
108         return f;
109 }
110
111 /* How the chip is configured. */
112 struct sam4_cfg {
113         uint32_t unique_id[4];
114
115         uint32_t slow_freq;
116         uint32_t rc_freq;
117         uint32_t mainosc_freq;
118         uint32_t plla_freq;
119         uint32_t mclk_freq;
120         uint32_t cpu_freq;
121         uint32_t fclk_freq;
122         uint32_t pclk0_freq;
123         uint32_t pclk1_freq;
124         uint32_t pclk2_freq;
125
126
127 #define SAM4_CHIPID_CIDR          (0x400E0740)
128         uint32_t CHIPID_CIDR;
129 #define SAM4_CHIPID_EXID          (0x400E0744)
130         uint32_t CHIPID_EXID;
131
132 #define SAM4_PMC_BASE             (0x400E0400)
133 #define SAM4_PMC_SCSR             (SAM4_PMC_BASE + 0x0008)
134         uint32_t PMC_SCSR;
135 #define SAM4_PMC_PCSR             (SAM4_PMC_BASE + 0x0018)
136         uint32_t PMC_PCSR;
137 #define SAM4_CKGR_UCKR            (SAM4_PMC_BASE + 0x001c)
138         uint32_t CKGR_UCKR;
139 #define SAM4_CKGR_MOR             (SAM4_PMC_BASE + 0x0020)
140         uint32_t CKGR_MOR;
141 #define SAM4_CKGR_MCFR            (SAM4_PMC_BASE + 0x0024)
142         uint32_t CKGR_MCFR;
143 #define SAM4_CKGR_PLLAR           (SAM4_PMC_BASE + 0x0028)
144         uint32_t CKGR_PLLAR;
145 #define SAM4_PMC_MCKR             (SAM4_PMC_BASE + 0x0030)
146         uint32_t PMC_MCKR;
147 #define SAM4_PMC_PCK0             (SAM4_PMC_BASE + 0x0040)
148         uint32_t PMC_PCK0;
149 #define SAM4_PMC_PCK1             (SAM4_PMC_BASE + 0x0044)
150         uint32_t PMC_PCK1;
151 #define SAM4_PMC_PCK2             (SAM4_PMC_BASE + 0x0048)
152         uint32_t PMC_PCK2;
153 #define SAM4_PMC_SR               (SAM4_PMC_BASE + 0x0068)
154         uint32_t PMC_SR;
155 #define SAM4_PMC_IMR              (SAM4_PMC_BASE + 0x006c)
156         uint32_t PMC_IMR;
157 #define SAM4_PMC_FSMR             (SAM4_PMC_BASE + 0x0070)
158         uint32_t PMC_FSMR;
159 #define SAM4_PMC_FSPR             (SAM4_PMC_BASE + 0x0074)
160         uint32_t PMC_FSPR;
161 };
162
163 struct sam4_bank_private {
164         int probed;
165         /* DANGER: THERE ARE DRAGONS HERE.. */
166         /* NOTE: If you add more 'ghost' pointers */
167         /* be aware that you must *manually* update */
168         /* these pointers in the function sam4_GetDetails() */
169         /* See the comment "Here there be dragons" */
170
171         /* so we can find the chip we belong to */
172         struct sam4_chip *pChip;
173         /* so we can find the original bank pointer */
174         struct flash_bank *pBank;
175         unsigned bank_number;
176         uint32_t controller_address;
177         uint32_t base_address;
178         uint32_t flash_wait_states;
179         bool present;
180         unsigned size_bytes;
181         unsigned nsectors;
182         unsigned sector_size;
183         unsigned page_size;
184 };
185
186 struct sam4_chip_details {
187         /* THERE ARE DRAGONS HERE.. */
188         /* note: If you add pointers here */
189         /* be careful about them as they */
190         /* may need to be updated inside */
191         /* the function: "sam4_GetDetails() */
192         /* which copy/overwrites the */
193         /* 'runtime' copy of this structure */
194         uint32_t chipid_cidr;
195         const char *name;
196
197         unsigned n_gpnvms;
198 #define SAM4_N_NVM_BITS 3
199         unsigned gpnvm[SAM4_N_NVM_BITS];
200         unsigned total_flash_size;
201         unsigned total_sram_size;
202         unsigned n_banks;
203 #define SAM4_MAX_FLASH_BANKS 2
204         /* these are "initialized" from the global const data */
205         struct sam4_bank_private bank[SAM4_MAX_FLASH_BANKS];
206 };
207
208 struct sam4_chip {
209         struct sam4_chip *next;
210         int probed;
211
212         /* this is "initialized" from the global const structure */
213         struct sam4_chip_details details;
214         struct target *target;
215         struct sam4_cfg cfg;
216 };
217
218
219 struct sam4_reg_list {
220         uint32_t address;  size_t struct_offset; const char *name;
221         void (*explain_func)(struct sam4_chip *pInfo);
222 };
223
224 static struct sam4_chip *all_sam4_chips;
225
226 static struct sam4_chip *get_current_sam4(struct command_context *cmd_ctx)
227 {
228         struct target *t;
229         static struct sam4_chip *p;
230
231         t = get_current_target(cmd_ctx);
232         if (!t) {
233                 command_print(cmd_ctx, "No current target?");
234                 return NULL;
235         }
236
237         p = all_sam4_chips;
238         if (!p) {
239                 /* this should not happen */
240                 /* the command is not registered until the chip is created? */
241                 command_print(cmd_ctx, "No SAM4 chips exist?");
242                 return NULL;
243         }
244
245         while (p) {
246                 if (p->target == t)
247                         return p;
248                 p = p->next;
249         }
250         command_print(cmd_ctx, "Cannot find SAM4 chip?");
251         return NULL;
252 }
253
254 /*The actual sector size of the SAM4S flash memory is 65536 bytes. 16 sectors for a 1024KB device*/
255 /*The lockregions are 8KB per lock region, with a 1024KB device having 128 lock regions. */
256 /*For the best results, nsectors are thus set to the amount of lock regions, and the sector_size*/
257 /*set to the lock region size.  Page erases are used to erase 8KB sections when programming*/
258
259 /* these are used to *initialize* the "pChip->details" structure. */
260 static const struct sam4_chip_details all_sam4_details[] = {
261
262         /* Start at91sam4e* series */
263         /*atsam4e16e - LQFP144/LFBGA144*/
264         {
265                 .chipid_cidr    = 0xA3CC0CE0,
266                 .name           = "at91sam4e16e",
267                 .total_flash_size     = 1024 * 1024,
268                 .total_sram_size      = 128 * 1024,
269                 .n_gpnvms       = 2,
270                 .n_banks        = 1,
271                 {
272 /*              .bank[0] = {*/
273                   {
274                         .probed = 0,
275                         .pChip  = NULL,
276                         .pBank  = NULL,
277                         .bank_number = 0,
278                         .base_address = FLASH_BANK_BASE_S,
279                         .controller_address = 0x400e0a00,
280                         .flash_wait_states = 6, /* workaround silicon bug */
281                         .present = 1,
282                         .size_bytes =  1024 * 1024,
283                         .nsectors   =  128,
284                         .sector_size = 8192,
285                         .page_size   = 512,
286                   },
287 /*              .bank[1] = {*/
288                   {
289                         .present = 0,
290                         .probed = 0,
291                         .bank_number = 1,
292
293                   },
294                 },
295         },
296
297         /* Start at91sam4n* series */
298         /*atsam4n8a - LQFP48/QFN48*/
299         {
300                 .chipid_cidr    = 0x293B0AE0,
301                 .name           = "at91sam4n8a",
302                 .total_flash_size     = 512 * 1024,
303                 .total_sram_size      = 64 * 1024,
304                 .n_gpnvms       = 2,
305                 .n_banks        = 1,
306                 {
307 /*              .bank[0] = {*/
308                   {
309                         .probed = 0,
310                         .pChip  = NULL,
311                         .pBank  = NULL,
312                         .bank_number = 0,
313                         .base_address = FLASH_BANK_BASE_S,
314                         .controller_address = 0x400e0a00,
315                         .flash_wait_states = 6, /* workaround silicon bug */
316                         .present = 1,
317                         .size_bytes =  512 * 1024,
318                         .nsectors   =  64,
319                         .sector_size = 8192,
320                         .page_size   = 512,
321                   },
322 /*              .bank[1] = {*/
323                   {
324                         .present = 0,
325                         .probed = 0,
326                         .bank_number = 1,
327
328                   },
329                 },
330         },
331         /*atsam4n8b - LQFP64/QFN64*/
332         {
333                 .chipid_cidr    = 0x294B0AE0,
334                 .name           = "at91sam4n8b",
335                 .total_flash_size     = 512 * 1024,
336                 .total_sram_size      = 64 * 1024,
337                 .n_gpnvms       = 2,
338                 .n_banks        = 1,
339                 {
340 /*              .bank[0] = {*/
341                   {
342                         .probed = 0,
343                         .pChip  = NULL,
344                         .pBank  = NULL,
345                         .bank_number = 0,
346                         .base_address = FLASH_BANK_BASE_S,
347                         .controller_address = 0x400e0a00,
348                         .flash_wait_states = 6, /* workaround silicon bug */
349                         .present = 1,
350                         .size_bytes =  512 * 1024,
351                         .nsectors   =  64,
352                         .sector_size = 8192,
353                         .page_size   = 512,
354                   },
355 /*              .bank[1] = {*/
356                   {
357                         .present = 0,
358                         .probed = 0,
359                         .bank_number = 1,
360
361                   },
362                 },
363         },
364         /*atsam4n8c - LQFP100/TFBGA100/VFBGA100*/
365         {
366                 .chipid_cidr    = 0x295B0AE0,
367                 .name           = "at91sam4n8c",
368                 .total_flash_size     = 512 * 1024,
369                 .total_sram_size      = 64 * 1024,
370                 .n_gpnvms       = 2,
371                 .n_banks        = 1,
372                 {
373 /*              .bank[0] = {*/
374                   {
375                         .probed = 0,
376                         .pChip  = NULL,
377                         .pBank  = NULL,
378                         .bank_number = 0,
379                         .base_address = FLASH_BANK_BASE_S,
380                         .controller_address = 0x400e0a00,
381                         .flash_wait_states = 6, /* workaround silicon bug */
382                         .present = 1,
383                         .size_bytes =  512 * 1024,
384                         .nsectors   =  64,
385                         .sector_size = 8192,
386                         .page_size   = 512,
387                   },
388 /*              .bank[1] = {*/
389                   {
390                         .present = 0,
391                         .probed = 0,
392                         .bank_number = 1,
393
394                   },
395                 },
396         },
397         /*atsam4n16b - LQFP64/QFN64*/
398         {
399                 .chipid_cidr    = 0x29460CE0,
400                 .name           = "at91sam4n16b",
401                 .total_flash_size     = 1024 * 1024,
402                 .total_sram_size      = 80 * 1024,
403                 .n_gpnvms       = 2,
404                 .n_banks        = 1,
405                 {
406 /*              .bank[0] = {*/
407                   {
408                         .probed = 0,
409                         .pChip  = NULL,
410                         .pBank  = NULL,
411                         .bank_number = 0,
412                         .base_address = FLASH_BANK_BASE_S,
413                         .controller_address = 0x400e0a00,
414                         .flash_wait_states = 6, /* workaround silicon bug */
415                         .present = 1,
416                         .size_bytes =  1024 * 1024,
417                         .nsectors   =  128,
418                         .sector_size = 8192,
419                         .page_size   = 512,
420                   },
421 /*              .bank[1] = {*/
422                   {
423                         .present = 0,
424                         .probed = 0,
425                         .bank_number = 1,
426
427                   },
428                 },
429         },
430         /*atsam4n16c - LQFP100/TFBGA100/VFBGA100*/
431         {
432                 .chipid_cidr    = 0x29560CE0,
433                 .name           = "at91sam4n16c",
434                 .total_flash_size     = 1024 * 1024,
435                 .total_sram_size      = 80 * 1024,
436                 .n_gpnvms       = 2,
437                 .n_banks        = 1,
438                 {
439 /*              .bank[0] = {*/
440                   {
441                         .probed = 0,
442                         .pChip  = NULL,
443                         .pBank  = NULL,
444                         .bank_number = 0,
445                         .base_address = FLASH_BANK_BASE_S,
446                         .controller_address = 0x400e0a00,
447                         .flash_wait_states = 6, /* workaround silicon bug */
448                         .present = 1,
449                         .size_bytes =  1024 * 1024,
450                         .nsectors   =  128,
451                         .sector_size = 8192,
452                         .page_size   = 512,
453                   },
454 /*              .bank[1] = {*/
455                   {
456                         .present = 0,
457                         .probed = 0,
458                         .bank_number = 1,
459
460                   },
461                 },
462         },
463
464         /* Start at91sam4s* series */
465         /*atsam4s16c - LQFP100/BGA100*/
466         {
467                 .chipid_cidr    = 0x28AC0CE0,
468                 .name           = "at91sam4s16c",
469                 .total_flash_size     = 1024 * 1024,
470                 .total_sram_size      = 128 * 1024,
471                 .n_gpnvms       = 2,
472                 .n_banks        = 1,
473                 {
474 /*              .bank[0] = {*/
475                   {
476                         .probed = 0,
477                         .pChip  = NULL,
478                         .pBank  = NULL,
479                         .bank_number = 0,
480                         .base_address = FLASH_BANK_BASE_S,
481                         .controller_address = 0x400e0a00,
482                         .flash_wait_states = 6, /* workaround silicon bug */
483                         .present = 1,
484                         .size_bytes =  1024 * 1024,
485                         .nsectors   =  128,
486                         .sector_size = 8192,
487                         .page_size   = 512,
488                   },
489 /*              .bank[1] = {*/
490                   {
491                         .present = 0,
492                         .probed = 0,
493                         .bank_number = 1,
494
495                   },
496                 },
497         },
498         /*atsam4s16b - LQFP64/QFN64*/
499         {
500                 .chipid_cidr    = 0x289C0CE0,
501                 .name           = "at91sam4s16b",
502                 .total_flash_size     = 1024 * 1024,
503                 .total_sram_size      = 128 * 1024,
504                 .n_gpnvms       = 2,
505                 .n_banks        = 1,
506                 {
507 /*              .bank[0] = {*/
508                   {
509                         .probed = 0,
510                         .pChip  = NULL,
511                         .pBank  = NULL,
512                         .bank_number = 0,
513                         .base_address = FLASH_BANK_BASE_S,
514                         .controller_address = 0x400e0a00,
515                         .flash_wait_states = 6, /* workaround silicon bug */
516                         .present = 1,
517                         .size_bytes =  1024 * 1024,
518                         .nsectors   =  128,
519                         .sector_size = 8192,
520                         .page_size   = 512,
521                   },
522 /*              .bank[1] = {*/
523                   {
524                         .present = 0,
525                         .probed = 0,
526                         .bank_number = 1,
527
528                   },
529                 },
530         },
531         /*atsam4sa16b - LQFP64/QFN64*/
532         {
533                 .chipid_cidr    = 0x28970CE0,
534                 .name           = "at91sam4sa16b",
535                 .total_flash_size     = 1024 * 1024,
536                 .total_sram_size      = 160 * 1024,
537                 .n_gpnvms       = 2,
538                 .n_banks        = 1,
539                 {
540 /*              .bank[0] = {*/
541                   {
542                         .probed = 0,
543                         .pChip  = NULL,
544                         .pBank  = NULL,
545                         .bank_number = 0,
546                         .base_address = FLASH_BANK_BASE_S,
547                         .controller_address = 0x400e0a00,
548                         .flash_wait_states = 6, /* workaround silicon bug */
549                         .present = 1,
550                         .size_bytes =  1024 * 1024,
551                         .nsectors   =  128,
552                         .sector_size = 8192,
553                         .page_size   = 512,
554                   },
555 /*              .bank[1] = {*/
556                   {
557                         .present = 0,
558                         .probed = 0,
559                         .bank_number = 1,
560
561                   },
562                 },
563         },
564         /*atsam4s16a - LQFP48/QFN48*/
565         {
566                 .chipid_cidr    = 0x288C0CE0,
567                 .name           = "at91sam4s16a",
568                 .total_flash_size     = 1024 * 1024,
569                 .total_sram_size      = 128 * 1024,
570                 .n_gpnvms       = 2,
571                 .n_banks        = 1,
572                 {
573 /*              .bank[0] = {*/
574                   {
575                         .probed = 0,
576                         .pChip  = NULL,
577                         .pBank  = NULL,
578                         .bank_number = 0,
579                         .base_address = FLASH_BANK_BASE_S,
580                         .controller_address = 0x400e0a00,
581                         .flash_wait_states = 6, /* workaround silicon bug */
582                         .present = 1,
583                         .size_bytes =  1024 * 1024,
584                         .nsectors   =  128,
585                         .sector_size = 8192,
586                         .page_size   = 512,
587                   },
588 /*              .bank[1] = {*/
589                   {
590                         .present = 0,
591                         .probed = 0,
592                         .bank_number = 1,
593
594                   },
595                 },
596         },
597         /*atsam4s8c - LQFP100/BGA100*/
598         {
599                 .chipid_cidr    = 0x28AC0AE0,
600                 .name           = "at91sam4s8c",
601                 .total_flash_size     = 512 * 1024,
602                 .total_sram_size      = 128 * 1024,
603                 .n_gpnvms       = 2,
604                 .n_banks        = 1,
605                 {
606 /*              .bank[0] = {*/
607                   {
608                         .probed = 0,
609                         .pChip  = NULL,
610                         .pBank  = NULL,
611                         .bank_number = 0,
612                         .base_address = FLASH_BANK_BASE_S,
613                         .controller_address = 0x400e0a00,
614                         .flash_wait_states = 6, /* workaround silicon bug */
615                         .present = 1,
616                         .size_bytes =  512 * 1024,
617                         .nsectors   =  64,
618                         .sector_size = 8192,
619                         .page_size   = 512,
620                   },
621 /*              .bank[1] = {*/
622                   {
623                         .present = 0,
624                         .probed = 0,
625                         .bank_number = 1,
626
627                   },
628                 },
629         },
630         /*atsam4s8b - LQFP64/BGA64*/
631         {
632                 .chipid_cidr    = 0x289C0AE0,
633                 .name           = "at91sam4s8b",
634                 .total_flash_size     = 512 * 1024,
635                 .total_sram_size      = 128 * 1024,
636                 .n_gpnvms       = 2,
637                 .n_banks        = 1,
638                 {
639 /*              .bank[0] = {*/
640                   {
641                         .probed = 0,
642                         .pChip  = NULL,
643                         .pBank  = NULL,
644                         .bank_number = 0,
645                         .base_address = FLASH_BANK_BASE_S,
646                         .controller_address = 0x400e0a00,
647                         .flash_wait_states = 6, /* workaround silicon bug */
648                         .present = 1,
649                         .size_bytes =  512 * 1024,
650                         .nsectors   =  64,
651                         .sector_size = 8192,
652                         .page_size   = 512,
653                   },
654 /*              .bank[1] = {*/
655                   {
656                         .present = 0,
657                         .probed = 0,
658                         .bank_number = 1,
659
660                   },
661                 },
662         },
663         /*atsam4s8a - LQFP48/BGA48*/
664         {
665                 .chipid_cidr    = 0x288C0AE0,
666                 .name           = "at91sam4s8a",
667                 .total_flash_size     = 512 * 1024,
668                 .total_sram_size      = 128 * 1024,
669                 .n_gpnvms       = 2,
670                 .n_banks        = 1,
671                 {
672 /*              .bank[0] = {*/
673                   {
674                         .probed = 0,
675                         .pChip  = NULL,
676                         .pBank  = NULL,
677                         .bank_number = 0,
678                         .base_address = FLASH_BANK_BASE_S,
679                         .controller_address = 0x400e0a00,
680                         .flash_wait_states = 6, /* workaround silicon bug */
681                         .present = 1,
682                         .size_bytes =  512 * 1024,
683                         .nsectors   =  64,
684                         .sector_size = 8192,
685                         .page_size   = 512,
686                   },
687 /*              .bank[1] = {*/
688                   {
689                         .present = 0,
690                         .probed = 0,
691                         .bank_number = 1,
692
693                   },
694                 },
695         },
696
697         /*atsam4s4a - LQFP48/BGA48*/
698         {
699                 .chipid_cidr    = 0x288b09e0,
700                 .name           = "at91sam4s4a",
701                 .total_flash_size     = 256 * 1024,
702                 .total_sram_size      = 64 * 1024,
703                 .n_gpnvms       = 2,
704                 .n_banks        = 1,
705                 {
706 /*              .bank[0] = {*/
707                   {
708                         .probed = 0,
709                         .pChip  = NULL,
710                         .pBank  = NULL,
711                         .bank_number = 0,
712                         .base_address = FLASH_BANK_BASE_S,
713                         .controller_address = 0x400e0a00,
714                         .flash_wait_states = 6, /* workaround silicon bug */
715                         .present = 1,
716                         .size_bytes =  256 * 1024,
717                         .nsectors   =  32,
718                         .sector_size = 8192,
719                         .page_size   = 512,
720                   },
721 /*              .bank[1] = {*/
722                   {
723                         .present = 0,
724                         .probed = 0,
725                         .bank_number = 1,
726
727                   },
728                 },
729         },
730
731         /*at91sam4sd32c*/
732         {
733                 .chipid_cidr    = 0x29a70ee0,
734                 .name           = "at91sam4sd32c",
735                 .total_flash_size     = 2048 * 1024,
736                 .total_sram_size      = 160 * 1024,
737                 .n_gpnvms       = 3,
738                 .n_banks        = 2,
739
740 /*              .bank[0] = { */
741                 {
742                         {
743                                 .probed = 0,
744                                 .pChip  = NULL,
745                                 .pBank  = NULL,
746                                 .bank_number = 0,
747                                 .base_address = FLASH_BANK0_BASE_SD,
748                                 .controller_address = 0x400e0a00,
749                                 .flash_wait_states = 6, /* workaround silicon bug */
750                                 .present = 1,
751                                 .size_bytes =  1024 * 1024,
752                                 .nsectors   =  128,
753                                 .sector_size = 8192,
754                                 .page_size   = 512,
755                         },
756
757 /*              .bank[1] = { */
758                         {
759                                 .probed = 0,
760                                 .pChip  = NULL,
761                                 .pBank  = NULL,
762                                 .bank_number = 1,
763                                 .base_address = FLASH_BANK1_BASE_2048K_SD,
764                                 .controller_address = 0x400e0c00,
765                                 .flash_wait_states = 6, /* workaround silicon bug */
766                                 .present = 1,
767                                 .size_bytes =  1024 * 1024,
768                                 .nsectors   =  128,
769                                 .sector_size = 8192,
770                                 .page_size   = 512,
771                         },
772                 },
773         },
774
775         /*at91sam4sd16c*/
776         {
777                 .chipid_cidr    = 0x29a70ce0,
778                 .name           = "at91sam4sd16c",
779                 .total_flash_size     = 1024 * 1024,
780                 .total_sram_size      = 160 * 1024,
781                 .n_gpnvms       = 3,
782                 .n_banks        = 2,
783
784 /*              .bank[0] = { */
785                 {
786                         {
787                                 .probed = 0,
788                                 .pChip  = NULL,
789                                 .pBank  = NULL,
790                                 .bank_number = 0,
791                                 .base_address = FLASH_BANK0_BASE_SD,
792                                 .controller_address = 0x400e0a00,
793                                 .flash_wait_states = 6, /* workaround silicon bug */
794                                 .present = 1,
795                                 .size_bytes =  512 * 1024,
796                                 .nsectors   =  64,
797                                 .sector_size = 8192,
798                                 .page_size   = 512,
799                         },
800
801 /*              .bank[1] = { */
802                         {
803                                 .probed = 0,
804                                 .pChip  = NULL,
805                                 .pBank  = NULL,
806                                 .bank_number = 1,
807                                 .base_address = FLASH_BANK1_BASE_1024K_SD,
808                                 .controller_address = 0x400e0c00,
809                                 .flash_wait_states = 6, /* workaround silicon bug */
810                                 .present = 1,
811                                 .size_bytes =  512 * 1024,
812                                 .nsectors   =  64,
813                                 .sector_size = 8192,
814                                 .page_size   = 512,
815                         },
816                 },
817         },
818
819         /*at91sam4sa16c*/
820         {
821                 .chipid_cidr    = 0x28a70ce0,
822                 .name           = "at91sam4sa16c",
823                 .total_flash_size     = 1024 * 1024,
824                 .total_sram_size      = 160 * 1024,
825                 .n_gpnvms       = 3,
826                 .n_banks        = 2,
827
828 /*              .bank[0] = { */
829                 {
830                         {
831                                 .probed = 0,
832                                 .pChip  = NULL,
833                                 .pBank  = NULL,
834                                 .bank_number = 0,
835                                 .base_address = FLASH_BANK0_BASE_SD,
836                                 .controller_address = 0x400e0a00,
837                                 .flash_wait_states = 6, /* workaround silicon bug */
838                                 .present = 1,
839                                 .size_bytes =  512 * 1024,
840                                 .nsectors   =  64,
841                                 .sector_size = 8192,
842                                 .page_size   = 512,
843                         },
844
845 /*              .bank[1] = { */
846                         {
847                                 .probed = 0,
848                                 .pChip  = NULL,
849                                 .pBank  = NULL,
850                                 .bank_number = 1,
851                                 .base_address = FLASH_BANK1_BASE_1024K_SD,
852                                 .controller_address = 0x400e0c00,
853                                 .flash_wait_states = 6, /* workaround silicon bug */
854                                 .present = 1,
855                                 .size_bytes =  512 * 1024,
856                                 .nsectors   =  64,
857                                 .sector_size = 8192,
858                                 .page_size   = 512,
859                         },
860                 },
861         },
862
863         /* at91samg53n19 */
864         {
865                 .chipid_cidr    = 0x247e0ae0,
866                 .name           = "at91samg53n19",
867                 .total_flash_size     = 512 * 1024,
868                 .total_sram_size      = 96 * 1024,
869                 .n_gpnvms       = 2,
870                 .n_banks        = 1,
871
872 /*              .bank[0] = {*/
873                 {
874                         {
875                                 .probed = 0,
876                                 .pChip  = NULL,
877                                 .pBank  = NULL,
878                                 .bank_number = 0,
879                                 .base_address = FLASH_BANK_BASE_S,
880                                 .controller_address = 0x400e0a00,
881                                 .flash_wait_states = 6, /* workaround silicon bug */
882                                 .present = 1,
883                                 .size_bytes =  512 * 1024,
884                                 .nsectors   =  64,
885                                 .sector_size = 8192,
886                                 .page_size   = 512,
887                         },
888 /*              .bank[1] = {*/
889                   {
890                         .present = 0,
891                         .probed = 0,
892                         .bank_number = 1,
893
894                   },
895                 }
896         },
897
898         /* terminate */
899         {
900                 .chipid_cidr    = 0,
901                 .name                   = NULL,
902         }
903 };
904
905 /* Globals above */
906 /***********************************************************************
907  **********************************************************************
908  **********************************************************************
909  **********************************************************************
910  **********************************************************************
911  **********************************************************************/
912 /* *ATMEL* style code - from the SAM4 driver code */
913
914 /**
915  * Get the current status of the EEFC and
916  * the value of some status bits (LOCKE, PROGE).
917  * @param pPrivate - info about the bank
918  * @param v        - result goes here
919  */
920 static int EFC_GetStatus(struct sam4_bank_private *pPrivate, uint32_t *v)
921 {
922         int r;
923         r = target_read_u32(pPrivate->pChip->target,
924                         pPrivate->controller_address + offset_EFC_FSR,
925                         v);
926         LOG_DEBUG("Status: 0x%08x (lockerror: %d, cmderror: %d, ready: %d)",
927                 (unsigned int)(*v),
928                 ((unsigned int)((*v >> 2) & 1)),
929                 ((unsigned int)((*v >> 1) & 1)),
930                 ((unsigned int)((*v >> 0) & 1)));
931
932         return r;
933 }
934
935 /**
936  * Get the result of the last executed command.
937  * @param pPrivate - info about the bank
938  * @param v        - result goes here
939  */
940 static int EFC_GetResult(struct sam4_bank_private *pPrivate, uint32_t *v)
941 {
942         int r;
943         uint32_t rv;
944         r = target_read_u32(pPrivate->pChip->target,
945                         pPrivate->controller_address + offset_EFC_FRR,
946                         &rv);
947         if (v)
948                 *v = rv;
949         LOG_DEBUG("Result: 0x%08x", ((unsigned int)(rv)));
950         return r;
951 }
952
953 static int EFC_StartCommand(struct sam4_bank_private *pPrivate,
954         unsigned command, unsigned argument)
955 {
956         uint32_t n, v;
957         int r;
958         int retry;
959
960         retry = 0;
961 do_retry:
962
963         /* Check command & argument */
964         switch (command) {
965
966                 case AT91C_EFC_FCMD_WP:
967                 case AT91C_EFC_FCMD_WPL:
968                 case AT91C_EFC_FCMD_EWP:
969                 case AT91C_EFC_FCMD_EWPL:
970                 /* case AT91C_EFC_FCMD_EPL: */
971                 case AT91C_EFC_FCMD_EPA:
972                 case AT91C_EFC_FCMD_SLB:
973                 case AT91C_EFC_FCMD_CLB:
974                         n = (pPrivate->size_bytes / pPrivate->page_size);
975                         if (argument >= n)
976                                 LOG_ERROR("*BUG*: Embedded flash has only %u pages", (unsigned)(n));
977                         break;
978
979                 case AT91C_EFC_FCMD_SFB:
980                 case AT91C_EFC_FCMD_CFB:
981                         if (argument >= pPrivate->pChip->details.n_gpnvms) {
982                                 LOG_ERROR("*BUG*: Embedded flash has only %d GPNVMs",
983                                                 pPrivate->pChip->details.n_gpnvms);
984                         }
985                         break;
986
987                 case AT91C_EFC_FCMD_GETD:
988                 case AT91C_EFC_FCMD_EA:
989                 case AT91C_EFC_FCMD_GLB:
990                 case AT91C_EFC_FCMD_GFB:
991                 case AT91C_EFC_FCMD_STUI:
992                 case AT91C_EFC_FCMD_SPUI:
993                         if (argument != 0)
994                                 LOG_ERROR("Argument is meaningless for cmd: %d", command);
995                         break;
996                 default:
997                         LOG_ERROR("Unknown command %d", command);
998                         break;
999         }
1000
1001         if (command == AT91C_EFC_FCMD_SPUI) {
1002                 /* this is a very special situation. */
1003                 /* Situation (1) - error/retry - see below */
1004                 /*      And we are being called recursively */
1005                 /* Situation (2) - normal, finished reading unique id */
1006         } else {
1007                 /* it should be "ready" */
1008                 EFC_GetStatus(pPrivate, &v);
1009                 if (v & 1) {
1010                         /* then it is ready */
1011                         /* we go on */
1012                 } else {
1013                         if (retry) {
1014                                 /* we have done this before */
1015                                 /* the controller is not responding. */
1016                                 LOG_ERROR("flash controller(%d) is not ready! Error",
1017                                         pPrivate->bank_number);
1018                                 return ERROR_FAIL;
1019                         } else {
1020                                 retry++;
1021                                 LOG_ERROR("Flash controller(%d) is not ready, attempting reset",
1022                                         pPrivate->bank_number);
1023                                 /* we do that by issuing the *STOP* command */
1024                                 EFC_StartCommand(pPrivate, AT91C_EFC_FCMD_SPUI, 0);
1025                                 /* above is recursive, and further recursion is blocked by */
1026                                 /* if (command == AT91C_EFC_FCMD_SPUI) above */
1027                                 goto do_retry;
1028                         }
1029                 }
1030         }
1031
1032         v = (0x5A << 24) | (argument << 8) | command;
1033         LOG_DEBUG("Command: 0x%08x", ((unsigned int)(v)));
1034         r = target_write_u32(pPrivate->pBank->target,
1035                         pPrivate->controller_address + offset_EFC_FCR, v);
1036         if (r != ERROR_OK)
1037                 LOG_DEBUG("Error Write failed");
1038         return r;
1039 }
1040
1041 /**
1042  * Performs the given command and wait until its completion (or an error).
1043  * @param pPrivate - info about the bank
1044  * @param command  - Command to perform.
1045  * @param argument - Optional command argument.
1046  * @param status   - put command status bits here
1047  */
1048 static int EFC_PerformCommand(struct sam4_bank_private *pPrivate,
1049         unsigned command,
1050         unsigned argument,
1051         uint32_t *status)
1052 {
1053
1054         int r;
1055         uint32_t v;
1056         int64_t ms_now, ms_end;
1057
1058         /* default */
1059         if (status)
1060                 *status = 0;
1061
1062         r = EFC_StartCommand(pPrivate, command, argument);
1063         if (r != ERROR_OK)
1064                 return r;
1065
1066         ms_end = 10000 + timeval_ms();
1067
1068         do {
1069                 r = EFC_GetStatus(pPrivate, &v);
1070                 if (r != ERROR_OK)
1071                         return r;
1072                 ms_now = timeval_ms();
1073                 if (ms_now > ms_end) {
1074                         /* error */
1075                         LOG_ERROR("Command timeout");
1076                         return ERROR_FAIL;
1077                 }
1078         } while ((v & 1) == 0);
1079
1080         /* error bits.. */
1081         if (status)
1082                 *status = (v & 0x6);
1083         return ERROR_OK;
1084
1085 }
1086
1087 /**
1088  * Read the unique ID.
1089  * @param pPrivate - info about the bank
1090  * The unique ID is stored in the 'pPrivate' structure.
1091  */
1092 static int FLASHD_ReadUniqueID(struct sam4_bank_private *pPrivate)
1093 {
1094         int r;
1095         uint32_t v;
1096         int x;
1097         /* assume 0 */
1098         pPrivate->pChip->cfg.unique_id[0] = 0;
1099         pPrivate->pChip->cfg.unique_id[1] = 0;
1100         pPrivate->pChip->cfg.unique_id[2] = 0;
1101         pPrivate->pChip->cfg.unique_id[3] = 0;
1102
1103         LOG_DEBUG("Begin");
1104         r = EFC_StartCommand(pPrivate, AT91C_EFC_FCMD_STUI, 0);
1105         if (r < 0)
1106                 return r;
1107
1108         for (x = 0; x < 4; x++) {
1109                 r = target_read_u32(pPrivate->pChip->target,
1110                                 pPrivate->pBank->base + (x * 4),
1111                                 &v);
1112                 if (r < 0)
1113                         return r;
1114                 pPrivate->pChip->cfg.unique_id[x] = v;
1115         }
1116
1117         r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_SPUI, 0, NULL);
1118         LOG_DEBUG("End: R=%d, id = 0x%08x, 0x%08x, 0x%08x, 0x%08x",
1119                 r,
1120                 (unsigned int)(pPrivate->pChip->cfg.unique_id[0]),
1121                 (unsigned int)(pPrivate->pChip->cfg.unique_id[1]),
1122                 (unsigned int)(pPrivate->pChip->cfg.unique_id[2]),
1123                 (unsigned int)(pPrivate->pChip->cfg.unique_id[3]));
1124         return r;
1125
1126 }
1127
1128 /**
1129  * Erases the entire flash.
1130  * @param pPrivate - the info about the bank.
1131  */
1132 static int FLASHD_EraseEntireBank(struct sam4_bank_private *pPrivate)
1133 {
1134         LOG_DEBUG("Here");
1135         return EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_EA, 0, NULL);
1136 }
1137
1138 /**
1139  * Erases the entire flash.
1140  * @param pPrivate - the info about the bank.
1141  */
1142 static int FLASHD_ErasePages(struct sam4_bank_private *pPrivate,
1143                                                          int firstPage,
1144                                                          int numPages,
1145                                                          uint32_t *status)
1146 {
1147         LOG_DEBUG("Here");
1148         uint8_t erasePages;
1149         switch (numPages)       {
1150                 case 4:
1151                         erasePages = 0x00;
1152                         break;
1153                 case 8:
1154                         erasePages = 0x01;
1155                         break;
1156                 case 16:
1157                         erasePages = 0x02;
1158                         break;
1159                 case 32:
1160                         erasePages = 0x03;
1161                         break;
1162                 default:
1163                         erasePages = 0x00;
1164                         break;
1165         }
1166
1167         /* AT91C_EFC_FCMD_EPA
1168          * According to the datasheet FARG[15:2] defines the page from which
1169          * the erase will start.This page must be modulo 4, 8, 16 or 32
1170          * according to the number of pages to erase. FARG[1:0] defines the
1171          * number of pages to be erased. Previously (firstpage << 2) was used
1172          * to conform to this, seems it should not be shifted...
1173          */
1174         return EFC_PerformCommand(pPrivate,
1175                 /* send Erase Page */
1176                 AT91C_EFC_FCMD_EPA,
1177                 (firstPage) | erasePages,
1178                 status);
1179 }
1180
1181 /**
1182  * Gets current GPNVM state.
1183  * @param pPrivate - info about the bank.
1184  * @param gpnvm    -  GPNVM bit index.
1185  * @param puthere  - result stored here.
1186  */
1187 /* ------------------------------------------------------------------------------ */
1188 static int FLASHD_GetGPNVM(struct sam4_bank_private *pPrivate, unsigned gpnvm, unsigned *puthere)
1189 {
1190         uint32_t v;
1191         int r;
1192
1193         LOG_DEBUG("Here");
1194         if (pPrivate->bank_number != 0) {
1195                 LOG_ERROR("GPNVM only works with Bank0");
1196                 return ERROR_FAIL;
1197         }
1198
1199         if (gpnvm >= pPrivate->pChip->details.n_gpnvms) {
1200                 LOG_ERROR("Invalid GPNVM %d, max: %d, ignored",
1201                         gpnvm, pPrivate->pChip->details.n_gpnvms);
1202                 return ERROR_FAIL;
1203         }
1204
1205         /* Get GPNVMs status */
1206         r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_GFB, 0, NULL);
1207         if (r != ERROR_OK) {
1208                 LOG_ERROR("Failed");
1209                 return r;
1210         }
1211
1212         r = EFC_GetResult(pPrivate, &v);
1213
1214         if (puthere) {
1215                 /* Check if GPNVM is set */
1216                 /* get the bit and make it a 0/1 */
1217                 *puthere = (v >> gpnvm) & 1;
1218         }
1219
1220         return r;
1221 }
1222
1223 /**
1224  * Clears the selected GPNVM bit.
1225  * @param pPrivate info about the bank
1226  * @param gpnvm GPNVM index.
1227  * @returns 0 if successful; otherwise returns an error code.
1228  */
1229 static int FLASHD_ClrGPNVM(struct sam4_bank_private *pPrivate, unsigned gpnvm)
1230 {
1231         int r;
1232         unsigned v;
1233
1234         LOG_DEBUG("Here");
1235         if (pPrivate->bank_number != 0) {
1236                 LOG_ERROR("GPNVM only works with Bank0");
1237                 return ERROR_FAIL;
1238         }
1239
1240         if (gpnvm >= pPrivate->pChip->details.n_gpnvms) {
1241                 LOG_ERROR("Invalid GPNVM %d, max: %d, ignored",
1242                         gpnvm, pPrivate->pChip->details.n_gpnvms);
1243                 return ERROR_FAIL;
1244         }
1245
1246         r = FLASHD_GetGPNVM(pPrivate, gpnvm, &v);
1247         if (r != ERROR_OK) {
1248                 LOG_DEBUG("Failed: %d", r);
1249                 return r;
1250         }
1251         r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_CFB, gpnvm, NULL);
1252         LOG_DEBUG("End: %d", r);
1253         return r;
1254 }
1255
1256 /**
1257  * Sets the selected GPNVM bit.
1258  * @param pPrivate info about the bank
1259  * @param gpnvm GPNVM index.
1260  */
1261 static int FLASHD_SetGPNVM(struct sam4_bank_private *pPrivate, unsigned gpnvm)
1262 {
1263         int r;
1264         unsigned v;
1265
1266         if (pPrivate->bank_number != 0) {
1267                 LOG_ERROR("GPNVM only works with Bank0");
1268                 return ERROR_FAIL;
1269         }
1270
1271         if (gpnvm >= pPrivate->pChip->details.n_gpnvms) {
1272                 LOG_ERROR("Invalid GPNVM %d, max: %d, ignored",
1273                         gpnvm, pPrivate->pChip->details.n_gpnvms);
1274                 return ERROR_FAIL;
1275         }
1276
1277         r = FLASHD_GetGPNVM(pPrivate, gpnvm, &v);
1278         if (r != ERROR_OK)
1279                 return r;
1280         if (v) {
1281                 /* already set */
1282                 r = ERROR_OK;
1283         } else {
1284                 /* set it */
1285                 r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_SFB, gpnvm, NULL);
1286         }
1287         return r;
1288 }
1289
1290 /**
1291  * Returns a bit field (at most 64) of locked regions within a page.
1292  * @param pPrivate info about the bank
1293  * @param v where to store locked bits
1294  */
1295 static int FLASHD_GetLockBits(struct sam4_bank_private *pPrivate, uint32_t *v)
1296 {
1297         int r;
1298         LOG_DEBUG("Here");
1299         r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_GLB, 0, NULL);
1300         if (r == ERROR_OK)      {
1301                 EFC_GetResult(pPrivate, v);
1302                 EFC_GetResult(pPrivate, v);
1303                 EFC_GetResult(pPrivate, v);
1304                 r = EFC_GetResult(pPrivate, v);
1305         }
1306         LOG_DEBUG("End: %d", r);
1307         return r;
1308 }
1309
1310 /**
1311  * Unlocks all the regions in the given address range.
1312  * @param pPrivate info about the bank
1313  * @param start_sector first sector to unlock
1314  * @param end_sector last (inclusive) to unlock
1315  */
1316
1317 static int FLASHD_Unlock(struct sam4_bank_private *pPrivate,
1318         unsigned start_sector,
1319         unsigned end_sector)
1320 {
1321         int r;
1322         uint32_t status;
1323         uint32_t pg;
1324         uint32_t pages_per_sector;
1325
1326         pages_per_sector = pPrivate->sector_size / pPrivate->page_size;
1327
1328         /* Unlock all pages */
1329         while (start_sector <= end_sector) {
1330                 pg = start_sector * pages_per_sector;
1331
1332                 r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_CLB, pg, &status);
1333                 if (r != ERROR_OK)
1334                         return r;
1335                 start_sector++;
1336         }
1337
1338         return ERROR_OK;
1339 }
1340
1341 /**
1342  * Locks regions
1343  * @param pPrivate - info about the bank
1344  * @param start_sector - first sector to lock
1345  * @param end_sector   - last sector (inclusive) to lock
1346  */
1347 static int FLASHD_Lock(struct sam4_bank_private *pPrivate,
1348         unsigned start_sector,
1349         unsigned end_sector)
1350 {
1351         uint32_t status;
1352         uint32_t pg;
1353         uint32_t pages_per_sector;
1354         int r;
1355
1356         pages_per_sector = pPrivate->sector_size / pPrivate->page_size;
1357
1358         /* Lock all pages */
1359         while (start_sector <= end_sector) {
1360                 pg = start_sector * pages_per_sector;
1361
1362                 r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_SLB, pg, &status);
1363                 if (r != ERROR_OK)
1364                         return r;
1365                 start_sector++;
1366         }
1367         return ERROR_OK;
1368 }
1369
1370 /****** END SAM4 CODE ********/
1371
1372 /* begin helpful debug code */
1373 /* print the fieldname, the field value, in dec & hex, and return field value */
1374 static uint32_t sam4_reg_fieldname(struct sam4_chip *pChip,
1375         const char *regname,
1376         uint32_t value,
1377         unsigned shift,
1378         unsigned width)
1379 {
1380         uint32_t v;
1381         int hwidth, dwidth;
1382
1383
1384         /* extract the field */
1385         v = value >> shift;
1386         v = v & ((1 << width)-1);
1387         if (width <= 16) {
1388                 hwidth = 4;
1389                 dwidth = 5;
1390         } else {
1391                 hwidth = 8;
1392                 dwidth = 12;
1393         }
1394
1395         /* show the basics */
1396         LOG_USER_N("\t%*s: %*" PRId32 " [0x%0*" PRIx32 "] ",
1397                 REG_NAME_WIDTH, regname,
1398                 dwidth, v,
1399                 hwidth, v);
1400         return v;
1401 }
1402
1403 static const char _unknown[] = "unknown";
1404 static const char *const eproc_names[] = {
1405         _unknown,                                       /* 0 */
1406         "arm946es",                                     /* 1 */
1407         "arm7tdmi",                                     /* 2 */
1408         "Cortex-M3",                            /* 3 */
1409         "arm920t",                                      /* 4 */
1410         "arm926ejs",                            /* 5 */
1411         "Cortex-A5",                            /* 6 */
1412         "Cortex-M4",                            /* 7 */
1413         _unknown,                                       /* 8 */
1414         _unknown,                                       /* 9 */
1415         _unknown,                                       /* 10 */
1416         _unknown,                                       /* 11 */
1417         _unknown,                                       /* 12 */
1418         _unknown,                                       /* 13 */
1419         _unknown,                                       /* 14 */
1420         _unknown,                                       /* 15 */
1421 };
1422
1423 #define nvpsize2 nvpsize                /* these two tables are identical */
1424 static const char *const nvpsize[] = {
1425         "none",                                         /*  0 */
1426         "8K bytes",                                     /*  1 */
1427         "16K bytes",                            /*  2 */
1428         "32K bytes",                            /*  3 */
1429         _unknown,                                       /*  4 */
1430         "64K bytes",                            /*  5 */
1431         _unknown,                                       /*  6 */
1432         "128K bytes",                           /*  7 */
1433         _unknown,                                       /*  8 */
1434         "256K bytes",                           /*  9 */
1435         "512K bytes",                           /* 10 */
1436         _unknown,                                       /* 11 */
1437         "1024K bytes",                          /* 12 */
1438         _unknown,                                       /* 13 */
1439         "2048K bytes",                          /* 14 */
1440         _unknown,                                       /* 15 */
1441 };
1442
1443 static const char *const sramsize[] = {
1444         "48K Bytes",                            /*  0 */
1445         "1K Bytes",                                     /*  1 */
1446         "2K Bytes",                                     /*  2 */
1447         "6K Bytes",                                     /*  3 */
1448         "112K Bytes",                           /*  4 */
1449         "4K Bytes",                                     /*  5 */
1450         "80K Bytes",                            /*  6 */
1451         "160K Bytes",                           /*  7 */
1452         "8K Bytes",                                     /*  8 */
1453         "16K Bytes",                            /*  9 */
1454         "32K Bytes",                            /* 10 */
1455         "64K Bytes",                            /* 11 */
1456         "128K Bytes",                           /* 12 */
1457         "256K Bytes",                           /* 13 */
1458         "96K Bytes",                            /* 14 */
1459         "512K Bytes",                           /* 15 */
1460
1461 };
1462
1463 static const struct archnames { unsigned value; const char *name; } archnames[] = {
1464         { 0x19,  "AT91SAM9xx Series"                                            },
1465         { 0x29,  "AT91SAM9XExx Series"                                          },
1466         { 0x34,  "AT91x34 Series"                                                       },
1467         { 0x37,  "CAP7 Series"                                                          },
1468         { 0x39,  "CAP9 Series"                                                          },
1469         { 0x3B,  "CAP11 Series"                                                         },
1470         { 0x3C, "ATSAM4E"                                                               },
1471         { 0x40,  "AT91x40 Series"                                                       },
1472         { 0x42,  "AT91x42 Series"                                                       },
1473         { 0x43,  "SAMG51 Series"
1474         },
1475         { 0x47,  "SAMG53 Series"
1476         },
1477         { 0x55,  "AT91x55 Series"                                                       },
1478         { 0x60,  "AT91SAM7Axx Series"                                           },
1479         { 0x61,  "AT91SAM7AQxx Series"                                          },
1480         { 0x63,  "AT91x63 Series"                                                       },
1481         { 0x70,  "AT91SAM7Sxx Series"                                           },
1482         { 0x71,  "AT91SAM7XCxx Series"                                          },
1483         { 0x72,  "AT91SAM7SExx Series"                                          },
1484         { 0x73,  "AT91SAM7Lxx Series"                                           },
1485         { 0x75,  "AT91SAM7Xxx Series"                                           },
1486         { 0x76,  "AT91SAM7SLxx Series"                                          },
1487         { 0x80,  "ATSAM3UxC Series (100-pin version)"           },
1488         { 0x81,  "ATSAM3UxE Series (144-pin version)"           },
1489         { 0x83,  "ATSAM3A/SAM4A xC Series (100-pin version)"},
1490         { 0x84,  "ATSAM3X/SAM4X xC Series (100-pin version)"},
1491         { 0x85,  "ATSAM3X/SAM4X xE Series (144-pin version)"},
1492         { 0x86,  "ATSAM3X/SAM4X xG Series (208/217-pin version)"        },
1493         { 0x88,  "ATSAM3S/SAM4S xA Series (48-pin version)"     },
1494         { 0x89,  "ATSAM3S/SAM4S xB Series (64-pin version)"     },
1495         { 0x8A,  "ATSAM3S/SAM4S xC Series (100-pin version)"},
1496         { 0x92,  "AT91x92 Series"                                                       },
1497         { 0x93,  "ATSAM3NxA Series (48-pin version)"            },
1498         { 0x94,  "ATSAM3NxB Series (64-pin version)"            },
1499         { 0x95,  "ATSAM3NxC Series (100-pin version)"           },
1500         { 0x98,  "ATSAM3SDxA Series (48-pin version)"           },
1501         { 0x99,  "ATSAM3SDxB Series (64-pin version)"           },
1502         { 0x9A,  "ATSAM3SDxC Series (100-pin version)"          },
1503         { 0xA5,  "ATSAM5A"                                                              },
1504         { 0xF0,  "AT75Cxx Series"                                                       },
1505         { -1, NULL },
1506 };
1507
1508 static const char *const nvptype[] = {
1509         "rom",  /* 0 */
1510         "romless or onchip flash",      /* 1 */
1511         "embedded flash memory",/* 2 */
1512         "rom(nvpsiz) + embedded flash (nvpsiz2)",       /* 3 */
1513         "sram emulating flash", /* 4 */
1514         _unknown,       /* 5 */
1515         _unknown,       /* 6 */
1516         _unknown,       /* 7 */
1517 };
1518
1519 static const char *_yes_or_no(uint32_t v)
1520 {
1521         if (v)
1522                 return "YES";
1523         else
1524                 return "NO";
1525 }
1526
1527 static const char *const _rc_freq[] = {
1528         "4 MHz", "8 MHz", "12 MHz", "reserved"
1529 };
1530
1531 static void sam4_explain_ckgr_mor(struct sam4_chip *pChip)
1532 {
1533         uint32_t v;
1534         uint32_t rcen;
1535
1536         v = sam4_reg_fieldname(pChip, "MOSCXTEN", pChip->cfg.CKGR_MOR, 0, 1);
1537         LOG_USER("(main xtal enabled: %s)", _yes_or_no(v));
1538         v = sam4_reg_fieldname(pChip, "MOSCXTBY", pChip->cfg.CKGR_MOR, 1, 1);
1539         LOG_USER("(main osc bypass: %s)", _yes_or_no(v));
1540         rcen = sam4_reg_fieldname(pChip, "MOSCRCEN", pChip->cfg.CKGR_MOR, 3, 1);
1541         LOG_USER("(onchip RC-OSC enabled: %s)", _yes_or_no(rcen));
1542         v = sam4_reg_fieldname(pChip, "MOSCRCF", pChip->cfg.CKGR_MOR, 4, 3);
1543         LOG_USER("(onchip RC-OSC freq: %s)", _rc_freq[v]);
1544
1545         pChip->cfg.rc_freq = 0;
1546         if (rcen) {
1547                 switch (v) {
1548                         default:
1549                                 pChip->cfg.rc_freq = 0;
1550                                 break;
1551                         case 0:
1552                                 pChip->cfg.rc_freq = 4 * 1000 * 1000;
1553                                 break;
1554                         case 1:
1555                                 pChip->cfg.rc_freq = 8 * 1000 * 1000;
1556                                 break;
1557                         case 2:
1558                                 pChip->cfg.rc_freq = 12 * 1000 * 1000;
1559                                 break;
1560                 }
1561         }
1562
1563         v = sam4_reg_fieldname(pChip, "MOSCXTST", pChip->cfg.CKGR_MOR, 8, 8);
1564         LOG_USER("(startup clks, time= %f uSecs)",
1565                 ((float)(v * 1000000)) / ((float)(pChip->cfg.slow_freq)));
1566         v = sam4_reg_fieldname(pChip, "MOSCSEL", pChip->cfg.CKGR_MOR, 24, 1);
1567         LOG_USER("(mainosc source: %s)",
1568                 v ? "external xtal" : "internal RC");
1569
1570         v = sam4_reg_fieldname(pChip, "CFDEN", pChip->cfg.CKGR_MOR, 25, 1);
1571         LOG_USER("(clock failure enabled: %s)",
1572                 _yes_or_no(v));
1573 }
1574
1575 static void sam4_explain_chipid_cidr(struct sam4_chip *pChip)
1576 {
1577         int x;
1578         uint32_t v;
1579         const char *cp;
1580
1581         sam4_reg_fieldname(pChip, "Version", pChip->cfg.CHIPID_CIDR, 0, 5);
1582         LOG_USER_N("\n");
1583
1584         v = sam4_reg_fieldname(pChip, "EPROC", pChip->cfg.CHIPID_CIDR, 5, 3);
1585         LOG_USER("%s", eproc_names[v]);
1586
1587         v = sam4_reg_fieldname(pChip, "NVPSIZE", pChip->cfg.CHIPID_CIDR, 8, 4);
1588         LOG_USER("%s", nvpsize[v]);
1589
1590         v = sam4_reg_fieldname(pChip, "NVPSIZE2", pChip->cfg.CHIPID_CIDR, 12, 4);
1591         LOG_USER("%s", nvpsize2[v]);
1592
1593         v = sam4_reg_fieldname(pChip, "SRAMSIZE", pChip->cfg.CHIPID_CIDR, 16, 4);
1594         LOG_USER("%s", sramsize[v]);
1595
1596         v = sam4_reg_fieldname(pChip, "ARCH", pChip->cfg.CHIPID_CIDR, 20, 8);
1597         cp = _unknown;
1598         for (x = 0; archnames[x].name; x++) {
1599                 if (v == archnames[x].value) {
1600                         cp = archnames[x].name;
1601                         break;
1602                 }
1603         }
1604
1605         LOG_USER("%s", cp);
1606
1607         v = sam4_reg_fieldname(pChip, "NVPTYP", pChip->cfg.CHIPID_CIDR, 28, 3);
1608         LOG_USER("%s", nvptype[v]);
1609
1610         v = sam4_reg_fieldname(pChip, "EXTID", pChip->cfg.CHIPID_CIDR, 31, 1);
1611         LOG_USER("(exists: %s)", _yes_or_no(v));
1612 }
1613
1614 static void sam4_explain_ckgr_mcfr(struct sam4_chip *pChip)
1615 {
1616         uint32_t v;
1617
1618         v = sam4_reg_fieldname(pChip, "MAINFRDY", pChip->cfg.CKGR_MCFR, 16, 1);
1619         LOG_USER("(main ready: %s)", _yes_or_no(v));
1620
1621         v = sam4_reg_fieldname(pChip, "MAINF", pChip->cfg.CKGR_MCFR, 0, 16);
1622
1623         v = (v * pChip->cfg.slow_freq) / 16;
1624         pChip->cfg.mainosc_freq = v;
1625
1626         LOG_USER("(%3.03f Mhz (%" PRIu32 ".%03" PRIu32 "khz slowclk)",
1627                 _tomhz(v),
1628                 (uint32_t)(pChip->cfg.slow_freq / 1000),
1629                 (uint32_t)(pChip->cfg.slow_freq % 1000));
1630 }
1631
1632 static void sam4_explain_ckgr_plla(struct sam4_chip *pChip)
1633 {
1634         uint32_t mula, diva;
1635
1636         diva = sam4_reg_fieldname(pChip, "DIVA", pChip->cfg.CKGR_PLLAR, 0, 8);
1637         LOG_USER_N("\n");
1638         mula = sam4_reg_fieldname(pChip, "MULA", pChip->cfg.CKGR_PLLAR, 16, 11);
1639         LOG_USER_N("\n");
1640         pChip->cfg.plla_freq = 0;
1641         if (mula == 0)
1642                 LOG_USER("\tPLLA Freq: (Disabled,mula = 0)");
1643         else if (diva == 0)
1644                 LOG_USER("\tPLLA Freq: (Disabled,diva = 0)");
1645         else if (diva >= 1) {
1646                 pChip->cfg.plla_freq = (pChip->cfg.mainosc_freq * (mula + 1) / diva);
1647                 LOG_USER("\tPLLA Freq: %3.03f MHz",
1648                         _tomhz(pChip->cfg.plla_freq));
1649         }
1650 }
1651
1652 static void sam4_explain_mckr(struct sam4_chip *pChip)
1653 {
1654         uint32_t css, pres, fin = 0;
1655         int pdiv = 0;
1656         const char *cp = NULL;
1657
1658         css = sam4_reg_fieldname(pChip, "CSS", pChip->cfg.PMC_MCKR, 0, 2);
1659         switch (css & 3) {
1660                 case 0:
1661                         fin = pChip->cfg.slow_freq;
1662                         cp = "slowclk";
1663                         break;
1664                 case 1:
1665                         fin = pChip->cfg.mainosc_freq;
1666                         cp  = "mainosc";
1667                         break;
1668                 case 2:
1669                         fin = pChip->cfg.plla_freq;
1670                         cp  = "plla";
1671                         break;
1672                 case 3:
1673                         if (pChip->cfg.CKGR_UCKR & (1 << 16)) {
1674                                 fin = 480 * 1000 * 1000;
1675                                 cp = "upll";
1676                         } else {
1677                                 fin = 0;
1678                                 cp  = "upll (*ERROR* UPLL is disabled)";
1679                         }
1680                         break;
1681                 default:
1682                         assert(0);
1683                         break;
1684         }
1685
1686         LOG_USER("%s (%3.03f Mhz)",
1687                 cp,
1688                 _tomhz(fin));
1689         pres = sam4_reg_fieldname(pChip, "PRES", pChip->cfg.PMC_MCKR, 4, 3);
1690         switch (pres & 0x07) {
1691                 case 0:
1692                         pdiv = 1;
1693                         cp = "selected clock";
1694                         break;
1695                 case 1:
1696                         pdiv = 2;
1697                         cp = "clock/2";
1698                         break;
1699                 case 2:
1700                         pdiv = 4;
1701                         cp = "clock/4";
1702                         break;
1703                 case 3:
1704                         pdiv = 8;
1705                         cp = "clock/8";
1706                         break;
1707                 case 4:
1708                         pdiv = 16;
1709                         cp = "clock/16";
1710                         break;
1711                 case 5:
1712                         pdiv = 32;
1713                         cp = "clock/32";
1714                         break;
1715                 case 6:
1716                         pdiv = 64;
1717                         cp = "clock/64";
1718                         break;
1719                 case 7:
1720                         pdiv = 6;
1721                         cp = "clock/6";
1722                         break;
1723                 default:
1724                         assert(0);
1725                         break;
1726         }
1727         LOG_USER("(%s)", cp);
1728         fin = fin / pdiv;
1729         /* sam4 has a *SINGLE* clock - */
1730         /* other at91 series parts have divisors for these. */
1731         pChip->cfg.cpu_freq = fin;
1732         pChip->cfg.mclk_freq = fin;
1733         pChip->cfg.fclk_freq = fin;
1734         LOG_USER("\t\tResult CPU Freq: %3.03f",
1735                 _tomhz(fin));
1736 }
1737
1738 #if 0
1739 static struct sam4_chip *target2sam4(struct target *pTarget)
1740 {
1741         struct sam4_chip *pChip;
1742
1743         if (pTarget == NULL)
1744                 return NULL;
1745
1746         pChip = all_sam4_chips;
1747         while (pChip) {
1748                 if (pChip->target == pTarget)
1749                         break;  /* return below */
1750                 else
1751                         pChip = pChip->next;
1752         }
1753         return pChip;
1754 }
1755 #endif
1756
1757 static uint32_t *sam4_get_reg_ptr(struct sam4_cfg *pCfg, const struct sam4_reg_list *pList)
1758 {
1759         /* this function exists to help */
1760         /* keep funky offsetof() errors */
1761         /* and casting from causing bugs */
1762
1763         /* By using prototypes - we can detect what would */
1764         /* be casting errors. */
1765
1766         return (uint32_t *)(void *)(((char *)(pCfg)) + pList->struct_offset);
1767 }
1768
1769
1770 #define SAM4_ENTRY(NAME, FUNC)  { .address = SAM4_ ## NAME, .struct_offset = offsetof( \
1771                                                   struct sam4_cfg, \
1772                                                   NAME), # NAME, FUNC }
1773 static const struct sam4_reg_list sam4_all_regs[] = {
1774         SAM4_ENTRY(CKGR_MOR, sam4_explain_ckgr_mor),
1775         SAM4_ENTRY(CKGR_MCFR, sam4_explain_ckgr_mcfr),
1776         SAM4_ENTRY(CKGR_PLLAR, sam4_explain_ckgr_plla),
1777         SAM4_ENTRY(CKGR_UCKR, NULL),
1778         SAM4_ENTRY(PMC_FSMR, NULL),
1779         SAM4_ENTRY(PMC_FSPR, NULL),
1780         SAM4_ENTRY(PMC_IMR, NULL),
1781         SAM4_ENTRY(PMC_MCKR, sam4_explain_mckr),
1782         SAM4_ENTRY(PMC_PCK0, NULL),
1783         SAM4_ENTRY(PMC_PCK1, NULL),
1784         SAM4_ENTRY(PMC_PCK2, NULL),
1785         SAM4_ENTRY(PMC_PCSR, NULL),
1786         SAM4_ENTRY(PMC_SCSR, NULL),
1787         SAM4_ENTRY(PMC_SR, NULL),
1788         SAM4_ENTRY(CHIPID_CIDR, sam4_explain_chipid_cidr),
1789         SAM4_ENTRY(CHIPID_EXID, NULL),
1790         /* TERMINATE THE LIST */
1791         { .name = NULL }
1792 };
1793 #undef SAM4_ENTRY
1794
1795 static struct sam4_bank_private *get_sam4_bank_private(struct flash_bank *bank)
1796 {
1797         return bank->driver_priv;
1798 }
1799
1800 /**
1801  * Given a pointer to where it goes in the structure,
1802  * determine the register name, address from the all registers table.
1803  */
1804 static const struct sam4_reg_list *sam4_GetReg(struct sam4_chip *pChip, uint32_t *goes_here)
1805 {
1806         const struct sam4_reg_list *pReg;
1807
1808         pReg = &(sam4_all_regs[0]);
1809         while (pReg->name) {
1810                 uint32_t *pPossible;
1811
1812                 /* calculate where this one go.. */
1813                 /* it is "possibly" this register. */
1814
1815                 pPossible = ((uint32_t *)(void *)(((char *)(&(pChip->cfg))) + pReg->struct_offset));
1816
1817                 /* well? Is it this register */
1818                 if (pPossible == goes_here) {
1819                         /* Jump for joy! */
1820                         return pReg;
1821                 }
1822
1823                 /* next... */
1824                 pReg++;
1825         }
1826         /* This is *TOTAL*PANIC* - we are totally screwed. */
1827         LOG_ERROR("INVALID SAM4 REGISTER");
1828         return NULL;
1829 }
1830
1831 static int sam4_ReadThisReg(struct sam4_chip *pChip, uint32_t *goes_here)
1832 {
1833         const struct sam4_reg_list *pReg;
1834         int r;
1835
1836         pReg = sam4_GetReg(pChip, goes_here);
1837         if (!pReg)
1838                 return ERROR_FAIL;
1839
1840         r = target_read_u32(pChip->target, pReg->address, goes_here);
1841         if (r != ERROR_OK) {
1842                 LOG_ERROR("Cannot read SAM4 register: %s @ 0x%08x, Err: %d",
1843                         pReg->name, (unsigned)(pReg->address), r);
1844         }
1845         return r;
1846 }
1847
1848 static int sam4_ReadAllRegs(struct sam4_chip *pChip)
1849 {
1850         int r;
1851         const struct sam4_reg_list *pReg;
1852
1853         pReg = &(sam4_all_regs[0]);
1854         while (pReg->name) {
1855                 r = sam4_ReadThisReg(pChip,
1856                                 sam4_get_reg_ptr(&(pChip->cfg), pReg));
1857                 if (r != ERROR_OK) {
1858                         LOG_ERROR("Cannot read SAM4 register: %s @ 0x%08x, Error: %d",
1859                                 pReg->name, ((unsigned)(pReg->address)), r);
1860                         return r;
1861                 }
1862                 pReg++;
1863         }
1864
1865         return ERROR_OK;
1866 }
1867
1868 static int sam4_GetInfo(struct sam4_chip *pChip)
1869 {
1870         const struct sam4_reg_list *pReg;
1871         uint32_t regval;
1872
1873         pReg = &(sam4_all_regs[0]);
1874         while (pReg->name) {
1875                 /* display all regs */
1876                 LOG_DEBUG("Start: %s", pReg->name);
1877                 regval = *sam4_get_reg_ptr(&(pChip->cfg), pReg);
1878                 LOG_USER("%*s: [0x%08" PRIx32 "] -> 0x%08" PRIx32,
1879                         REG_NAME_WIDTH,
1880                         pReg->name,
1881                         pReg->address,
1882                         regval);
1883                 if (pReg->explain_func)
1884                         (*(pReg->explain_func))(pChip);
1885                 LOG_DEBUG("End: %s", pReg->name);
1886                 pReg++;
1887         }
1888         LOG_USER("   rc-osc: %3.03f MHz", _tomhz(pChip->cfg.rc_freq));
1889         LOG_USER("  mainosc: %3.03f MHz", _tomhz(pChip->cfg.mainosc_freq));
1890         LOG_USER("     plla: %3.03f MHz", _tomhz(pChip->cfg.plla_freq));
1891         LOG_USER(" cpu-freq: %3.03f MHz", _tomhz(pChip->cfg.cpu_freq));
1892         LOG_USER("mclk-freq: %3.03f MHz", _tomhz(pChip->cfg.mclk_freq));
1893
1894         LOG_USER(" UniqueId: 0x%08" PRIx32 " 0x%08" PRIx32 " 0x%08" PRIx32 " 0x%08"PRIx32,
1895                 pChip->cfg.unique_id[0],
1896                 pChip->cfg.unique_id[1],
1897                 pChip->cfg.unique_id[2],
1898                 pChip->cfg.unique_id[3]);
1899
1900         return ERROR_OK;
1901 }
1902
1903 static int sam4_protect_check(struct flash_bank *bank)
1904 {
1905         int r;
1906         uint32_t v[4] = {0};
1907         unsigned x;
1908         struct sam4_bank_private *pPrivate;
1909
1910         LOG_DEBUG("Begin");
1911         if (bank->target->state != TARGET_HALTED) {
1912                 LOG_ERROR("Target not halted");
1913                 return ERROR_TARGET_NOT_HALTED;
1914         }
1915
1916         pPrivate = get_sam4_bank_private(bank);
1917         if (!pPrivate) {
1918                 LOG_ERROR("no private for this bank?");
1919                 return ERROR_FAIL;
1920         }
1921         if (!(pPrivate->probed))
1922                 return ERROR_FLASH_BANK_NOT_PROBED;
1923
1924         r = FLASHD_GetLockBits(pPrivate, v);
1925         if (r != ERROR_OK) {
1926                 LOG_DEBUG("Failed: %d", r);
1927                 return r;
1928         }
1929
1930         for (x = 0; x < pPrivate->nsectors; x++)
1931                 bank->sectors[x].is_protected = (!!(v[x >> 5] & (1 << (x % 32))));
1932         LOG_DEBUG("Done");
1933         return ERROR_OK;
1934 }
1935
1936 FLASH_BANK_COMMAND_HANDLER(sam4_flash_bank_command)
1937 {
1938         struct sam4_chip *pChip;
1939
1940         pChip = all_sam4_chips;
1941
1942         /* is this an existing chip? */
1943         while (pChip) {
1944                 if (pChip->target == bank->target)
1945                         break;
1946                 pChip = pChip->next;
1947         }
1948
1949         if (!pChip) {
1950                 /* this is a *NEW* chip */
1951                 pChip = calloc(1, sizeof(struct sam4_chip));
1952                 if (!pChip) {
1953                         LOG_ERROR("NO RAM!");
1954                         return ERROR_FAIL;
1955                 }
1956                 pChip->target = bank->target;
1957                 /* insert at head */
1958                 pChip->next = all_sam4_chips;
1959                 all_sam4_chips = pChip;
1960                 pChip->target = bank->target;
1961                 /* assumption is this runs at 32khz */
1962                 pChip->cfg.slow_freq = 32768;
1963                 pChip->probed = 0;
1964         }
1965
1966         switch (bank->base) {
1967                 default:
1968                         LOG_ERROR("Address 0x%08x invalid bank address (try 0x%08x"
1969                                 "[at91sam4s series] )",
1970                                 ((unsigned int)(bank->base)),
1971                                 ((unsigned int)(FLASH_BANK_BASE_S)));
1972                         return ERROR_FAIL;
1973                         break;
1974
1975                 /* at91sam4s series only has bank 0*/
1976                 /* at91sam4sd series has the same address for bank 0 (FLASH_BANK0_BASE_SD)*/
1977                 case FLASH_BANK_BASE_S:
1978                         bank->driver_priv = &(pChip->details.bank[0]);
1979                         bank->bank_number = 0;
1980                         pChip->details.bank[0].pChip = pChip;
1981                         pChip->details.bank[0].pBank = bank;
1982                         break;
1983
1984                 /* Bank 1 of at91sam4sd series */
1985                 case FLASH_BANK1_BASE_1024K_SD:
1986                 case FLASH_BANK1_BASE_2048K_SD:
1987                         bank->driver_priv = &(pChip->details.bank[1]);
1988                         bank->bank_number = 1;
1989                         pChip->details.bank[1].pChip = pChip;
1990                         pChip->details.bank[1].pBank = bank;
1991                         break;
1992         }
1993
1994         /* we initialize after probing. */
1995         return ERROR_OK;
1996 }
1997
1998 static int sam4_GetDetails(struct sam4_bank_private *pPrivate)
1999 {
2000         const struct sam4_chip_details *pDetails;
2001         struct sam4_chip *pChip;
2002         struct flash_bank *saved_banks[SAM4_MAX_FLASH_BANKS];
2003         unsigned x;
2004
2005         LOG_DEBUG("Begin");
2006         pDetails = all_sam4_details;
2007         while (pDetails->name) {
2008                 /* Compare cidr without version bits */
2009                 if (pDetails->chipid_cidr == (pPrivate->pChip->cfg.CHIPID_CIDR & 0xFFFFFFE0))
2010                         break;
2011                 else
2012                         pDetails++;
2013         }
2014         if (pDetails->name == NULL) {
2015                 LOG_ERROR("SAM4 ChipID 0x%08x not found in table (perhaps you can ID this chip?)",
2016                         (unsigned int)(pPrivate->pChip->cfg.CHIPID_CIDR));
2017                 /* Help the victim, print details about the chip */
2018                 LOG_INFO("SAM4 CHIPID_CIDR: 0x%08" PRIx32 " decodes as follows",
2019                         pPrivate->pChip->cfg.CHIPID_CIDR);
2020                 sam4_explain_chipid_cidr(pPrivate->pChip);
2021                 return ERROR_FAIL;
2022         }
2023
2024         /* DANGER: THERE ARE DRAGONS HERE */
2025
2026         /* get our pChip - it is going */
2027         /* to be over-written shortly */
2028         pChip = pPrivate->pChip;
2029
2030         /* Note that, in reality: */
2031         /*  */
2032         /*     pPrivate = &(pChip->details.bank[0]) */
2033         /* or  pPrivate = &(pChip->details.bank[1]) */
2034         /*  */
2035
2036         /* save the "bank" pointers */
2037         for (x = 0; x < SAM4_MAX_FLASH_BANKS; x++)
2038                 saved_banks[x] = pChip->details.bank[x].pBank;
2039
2040         /* Overwrite the "details" structure. */
2041         memcpy(&(pPrivate->pChip->details),
2042                 pDetails,
2043                 sizeof(pPrivate->pChip->details));
2044
2045         /* now fix the ghosted pointers */
2046         for (x = 0; x < SAM4_MAX_FLASH_BANKS; x++) {
2047                 pChip->details.bank[x].pChip = pChip;
2048                 pChip->details.bank[x].pBank = saved_banks[x];
2049         }
2050
2051         /* update the *BANK*SIZE* */
2052
2053         LOG_DEBUG("End");
2054         return ERROR_OK;
2055 }
2056
2057 static int _sam4_probe(struct flash_bank *bank, int noise)
2058 {
2059         unsigned x;
2060         int r;
2061         struct sam4_bank_private *pPrivate;
2062
2063
2064         LOG_DEBUG("Begin: Bank: %d, Noise: %d", bank->bank_number, noise);
2065         if (bank->target->state != TARGET_HALTED) {
2066                 LOG_ERROR("Target not halted");
2067                 return ERROR_TARGET_NOT_HALTED;
2068         }
2069
2070         pPrivate = get_sam4_bank_private(bank);
2071         if (!pPrivate) {
2072                 LOG_ERROR("Invalid/unknown bank number");
2073                 return ERROR_FAIL;
2074         }
2075
2076         r = sam4_ReadAllRegs(pPrivate->pChip);
2077         if (r != ERROR_OK)
2078                 return r;
2079
2080         LOG_DEBUG("Here");
2081         if (pPrivate->pChip->probed)
2082                 r = sam4_GetInfo(pPrivate->pChip);
2083         else
2084                 r = sam4_GetDetails(pPrivate);
2085         if (r != ERROR_OK)
2086                 return r;
2087
2088         /* update the flash bank size */
2089         for (x = 0; x < SAM4_MAX_FLASH_BANKS; x++) {
2090                 if (bank->base == pPrivate->pChip->details.bank[x].base_address) {
2091                         bank->size = pPrivate->pChip->details.bank[x].size_bytes;
2092                         break;
2093                 }
2094         }
2095
2096         if (bank->sectors == NULL) {
2097                 bank->sectors = calloc(pPrivate->nsectors, (sizeof((bank->sectors)[0])));
2098                 if (bank->sectors == NULL) {
2099                         LOG_ERROR("No memory!");
2100                         return ERROR_FAIL;
2101                 }
2102                 bank->num_sectors = pPrivate->nsectors;
2103
2104                 for (x = 0; ((int)(x)) < bank->num_sectors; x++) {
2105                         bank->sectors[x].size = pPrivate->sector_size;
2106                         bank->sectors[x].offset = x * (pPrivate->sector_size);
2107                         /* mark as unknown */
2108                         bank->sectors[x].is_erased = -1;
2109                         bank->sectors[x].is_protected = -1;
2110                 }
2111         }
2112
2113         pPrivate->probed = 1;
2114
2115         r = sam4_protect_check(bank);
2116         if (r != ERROR_OK)
2117                 return r;
2118
2119         LOG_DEBUG("Bank = %d, nbanks = %d",
2120                 pPrivate->bank_number, pPrivate->pChip->details.n_banks);
2121         if ((pPrivate->bank_number + 1) == pPrivate->pChip->details.n_banks) {
2122                 /* read unique id, */
2123                 /* it appears to be associated with the *last* flash bank. */
2124                 FLASHD_ReadUniqueID(pPrivate);
2125         }
2126
2127         return r;
2128 }
2129
2130 static int sam4_probe(struct flash_bank *bank)
2131 {
2132         return _sam4_probe(bank, 1);
2133 }
2134
2135 static int sam4_auto_probe(struct flash_bank *bank)
2136 {
2137         return _sam4_probe(bank, 0);
2138 }
2139
2140 static int sam4_erase(struct flash_bank *bank, int first, int last)
2141 {
2142         struct sam4_bank_private *pPrivate;
2143         int r;
2144         int i;
2145         int pageCount;
2146         /*16 pages equals 8KB - Same size as a lock region*/
2147         pageCount = 16;
2148         uint32_t status;
2149
2150         LOG_DEBUG("Here");
2151         if (bank->target->state != TARGET_HALTED) {
2152                 LOG_ERROR("Target not halted");
2153                 return ERROR_TARGET_NOT_HALTED;
2154         }
2155
2156         r = sam4_auto_probe(bank);
2157         if (r != ERROR_OK) {
2158                 LOG_DEBUG("Here,r=%d", r);
2159                 return r;
2160         }
2161
2162         pPrivate = get_sam4_bank_private(bank);
2163         if (!(pPrivate->probed))
2164                 return ERROR_FLASH_BANK_NOT_PROBED;
2165
2166         if ((first == 0) && ((last + 1) == ((int)(pPrivate->nsectors)))) {
2167                 /* whole chip */
2168                 LOG_DEBUG("Here");
2169                 return FLASHD_EraseEntireBank(pPrivate);
2170         }
2171         LOG_INFO("sam4 does not auto-erase while programming (Erasing relevant sectors)");
2172         LOG_INFO("sam4 First: 0x%08x Last: 0x%08x", (unsigned int)(first), (unsigned int)(last));
2173         for (i = first; i <= last; i++) {
2174                 /*16 pages equals 8KB - Same size as a lock region*/
2175                 r = FLASHD_ErasePages(pPrivate, (i * pageCount), pageCount, &status);
2176                 LOG_INFO("Erasing sector: 0x%08x", (unsigned int)(i));
2177                 if (r != ERROR_OK)
2178                         LOG_ERROR("SAM4: Error performing Erase page @ lock region number %d",
2179                                 (unsigned int)(i));
2180                 if (status & (1 << 2)) {
2181                         LOG_ERROR("SAM4: Lock Region %d is locked", (unsigned int)(i));
2182                         return ERROR_FAIL;
2183                 }
2184                 if (status & (1 << 1)) {
2185                         LOG_ERROR("SAM4: Flash Command error @lock region %d", (unsigned int)(i));
2186                         return ERROR_FAIL;
2187                 }
2188         }
2189
2190         return ERROR_OK;
2191 }
2192
2193 static int sam4_protect(struct flash_bank *bank, int set, int first, int last)
2194 {
2195         struct sam4_bank_private *pPrivate;
2196         int r;
2197
2198         LOG_DEBUG("Here");
2199         if (bank->target->state != TARGET_HALTED) {
2200                 LOG_ERROR("Target not halted");
2201                 return ERROR_TARGET_NOT_HALTED;
2202         }
2203
2204         pPrivate = get_sam4_bank_private(bank);
2205         if (!(pPrivate->probed))
2206                 return ERROR_FLASH_BANK_NOT_PROBED;
2207
2208         if (set)
2209                 r = FLASHD_Lock(pPrivate, (unsigned)(first), (unsigned)(last));
2210         else
2211                 r = FLASHD_Unlock(pPrivate, (unsigned)(first), (unsigned)(last));
2212         LOG_DEBUG("End: r=%d", r);
2213
2214         return r;
2215
2216 }
2217
2218 static int sam4_page_read(struct sam4_bank_private *pPrivate, unsigned pagenum, uint8_t *buf)
2219 {
2220         uint32_t adr;
2221         int r;
2222
2223         adr = pagenum * pPrivate->page_size;
2224         adr = adr + pPrivate->base_address;
2225
2226         r = target_read_memory(pPrivate->pChip->target,
2227                         adr,
2228                         4,                                      /* THIS*MUST*BE* in 32bit values */
2229                         pPrivate->page_size / 4,
2230                         buf);
2231         if (r != ERROR_OK)
2232                 LOG_ERROR("SAM4: Flash program failed to read page phys address: 0x%08x",
2233                         (unsigned int)(adr));
2234         return r;
2235 }
2236
2237 static int sam4_page_write(struct sam4_bank_private *pPrivate, unsigned pagenum, const uint8_t *buf)
2238 {
2239         uint32_t adr;
2240         uint32_t status;
2241         uint32_t fmr;   /* EEFC Flash Mode Register */
2242         int r;
2243
2244         adr = pagenum * pPrivate->page_size;
2245         adr = (adr + pPrivate->base_address);
2246
2247         /* Get flash mode register value */
2248         r = target_read_u32(pPrivate->pChip->target, pPrivate->controller_address, &fmr);
2249         if (r != ERROR_OK)
2250                 LOG_DEBUG("Error Read failed: read flash mode register");
2251
2252         /* Clear flash wait state field */
2253         fmr &= 0xfffff0ff;
2254
2255         /* set FWS (flash wait states) field in the FMR (flash mode register) */
2256         fmr |= (pPrivate->flash_wait_states << 8);
2257
2258         LOG_DEBUG("Flash Mode: 0x%08x", ((unsigned int)(fmr)));
2259         r = target_write_u32(pPrivate->pBank->target, pPrivate->controller_address, fmr);
2260         if (r != ERROR_OK)
2261                 LOG_DEBUG("Error Write failed: set flash mode register");
2262
2263         /* 1st sector 8kBytes - page 0 - 15*/
2264         /* 2nd sector 8kBytes - page 16 - 30*/
2265         /* 3rd sector 48kBytes - page 31 - 127*/
2266         LOG_DEBUG("Wr Page %u @ phys address: 0x%08x", pagenum, (unsigned int)(adr));
2267         r = target_write_memory(pPrivate->pChip->target,
2268                         adr,
2269                         4,                                      /* THIS*MUST*BE* in 32bit values */
2270                         pPrivate->page_size / 4,
2271                         buf);
2272         if (r != ERROR_OK) {
2273                 LOG_ERROR("SAM4: Failed to write (buffer) page at phys address 0x%08x",
2274                         (unsigned int)(adr));
2275                 return r;
2276         }
2277
2278         r = EFC_PerformCommand(pPrivate,
2279                         /* send Erase & Write Page */
2280                         AT91C_EFC_FCMD_WP,      /*AT91C_EFC_FCMD_EWP only works on first two 8kb sectors*/
2281                         pagenum,
2282                         &status);
2283
2284         if (r != ERROR_OK)
2285                 LOG_ERROR("SAM4: Error performing Write page @ phys address 0x%08x",
2286                         (unsigned int)(adr));
2287         if (status & (1 << 2)) {
2288                 LOG_ERROR("SAM4: Page @ Phys address 0x%08x is locked", (unsigned int)(adr));
2289                 return ERROR_FAIL;
2290         }
2291         if (status & (1 << 1)) {
2292                 LOG_ERROR("SAM4: Flash Command error @phys address 0x%08x", (unsigned int)(adr));
2293                 return ERROR_FAIL;
2294         }
2295         return ERROR_OK;
2296 }
2297
2298 static int sam4_write(struct flash_bank *bank,
2299         const uint8_t *buffer,
2300         uint32_t offset,
2301         uint32_t count)
2302 {
2303         int n;
2304         unsigned page_cur;
2305         unsigned page_end;
2306         int r;
2307         unsigned page_offset;
2308         struct sam4_bank_private *pPrivate;
2309         uint8_t *pagebuffer;
2310
2311         /* incase we bail further below, set this to null */
2312         pagebuffer = NULL;
2313
2314         /* ignore dumb requests */
2315         if (count == 0) {
2316                 r = ERROR_OK;
2317                 goto done;
2318         }
2319
2320         if (bank->target->state != TARGET_HALTED) {
2321                 LOG_ERROR("Target not halted");
2322                 r = ERROR_TARGET_NOT_HALTED;
2323                 goto done;
2324         }
2325
2326         pPrivate = get_sam4_bank_private(bank);
2327         if (!(pPrivate->probed)) {
2328                 r = ERROR_FLASH_BANK_NOT_PROBED;
2329                 goto done;
2330         }
2331
2332         if ((offset + count) > pPrivate->size_bytes) {
2333                 LOG_ERROR("Flash write error - past end of bank");
2334                 LOG_ERROR(" offset: 0x%08x, count 0x%08x, BankEnd: 0x%08x",
2335                         (unsigned int)(offset),
2336                         (unsigned int)(count),
2337                         (unsigned int)(pPrivate->size_bytes));
2338                 r = ERROR_FAIL;
2339                 goto done;
2340         }
2341
2342         pagebuffer = malloc(pPrivate->page_size);
2343         if (!pagebuffer) {
2344                 LOG_ERROR("No memory for %d Byte page buffer", (int)(pPrivate->page_size));
2345                 r = ERROR_FAIL;
2346                 goto done;
2347         }
2348
2349         /* what page do we start & end in? */
2350         page_cur = offset / pPrivate->page_size;
2351         page_end = (offset + count - 1) / pPrivate->page_size;
2352
2353         LOG_DEBUG("Offset: 0x%08x, Count: 0x%08x", (unsigned int)(offset), (unsigned int)(count));
2354         LOG_DEBUG("Page start: %d, Page End: %d", (int)(page_cur), (int)(page_end));
2355
2356         /* Special case: all one page */
2357         /*  */
2358         /* Otherwise: */
2359         /*    (1) non-aligned start */
2360         /*    (2) body pages */
2361         /*    (3) non-aligned end. */
2362
2363         /* Handle special case - all one page. */
2364         if (page_cur == page_end) {
2365                 LOG_DEBUG("Special case, all in one page");
2366                 r = sam4_page_read(pPrivate, page_cur, pagebuffer);
2367                 if (r != ERROR_OK)
2368                         goto done;
2369
2370                 page_offset = (offset & (pPrivate->page_size-1));
2371                 memcpy(pagebuffer + page_offset,
2372                         buffer,
2373                         count);
2374
2375                 r = sam4_page_write(pPrivate, page_cur, pagebuffer);
2376                 if (r != ERROR_OK)
2377                         goto done;
2378                 r = ERROR_OK;
2379                 goto done;
2380         }
2381
2382         /* non-aligned start */
2383         page_offset = offset & (pPrivate->page_size - 1);
2384         if (page_offset) {
2385                 LOG_DEBUG("Not-Aligned start");
2386                 /* read the partial */
2387                 r = sam4_page_read(pPrivate, page_cur, pagebuffer);
2388                 if (r != ERROR_OK)
2389                         goto done;
2390
2391                 /* over-write with new data */
2392                 n = (pPrivate->page_size - page_offset);
2393                 memcpy(pagebuffer + page_offset,
2394                         buffer,
2395                         n);
2396
2397                 r = sam4_page_write(pPrivate, page_cur, pagebuffer);
2398                 if (r != ERROR_OK)
2399                         goto done;
2400
2401                 count  -= n;
2402                 offset += n;
2403                 buffer += n;
2404                 page_cur++;
2405         }
2406
2407         /* By checking that offset is correct here, we also
2408         fix a clang warning */
2409         assert(offset % pPrivate->page_size == 0);
2410
2411         /* intermediate large pages */
2412         /* also - the final *terminal* */
2413         /* if that terminal page is a full page */
2414         LOG_DEBUG("Full Page Loop: cur=%d, end=%d, count = 0x%08x",
2415                 (int)page_cur, (int)page_end, (unsigned int)(count));
2416
2417         while ((page_cur < page_end) &&
2418                         (count >= pPrivate->page_size)) {
2419                 r = sam4_page_write(pPrivate, page_cur, buffer);
2420                 if (r != ERROR_OK)
2421                         goto done;
2422                 count -= pPrivate->page_size;
2423                 buffer += pPrivate->page_size;
2424                 page_cur += 1;
2425         }
2426
2427         /* terminal partial page? */
2428         if (count) {
2429                 LOG_DEBUG("Terminal partial page, count = 0x%08x", (unsigned int)(count));
2430                 /* we have a partial page */
2431                 r = sam4_page_read(pPrivate, page_cur, pagebuffer);
2432                 if (r != ERROR_OK)
2433                         goto done;
2434                                         /* data goes at start */
2435                 memcpy(pagebuffer, buffer, count);
2436                 r = sam4_page_write(pPrivate, page_cur, pagebuffer);
2437                 if (r != ERROR_OK)
2438                         goto done;
2439         }
2440         LOG_DEBUG("Done!");
2441         r = ERROR_OK;
2442 done:
2443         if (pagebuffer)
2444                 free(pagebuffer);
2445         return r;
2446 }
2447
2448 COMMAND_HANDLER(sam4_handle_info_command)
2449 {
2450         struct sam4_chip *pChip;
2451         pChip = get_current_sam4(CMD_CTX);
2452         if (!pChip)
2453                 return ERROR_OK;
2454
2455         unsigned x;
2456         int r;
2457
2458         /* bank0 must exist before we can do anything */
2459         if (pChip->details.bank[0].pBank == NULL) {
2460                 x = 0;
2461 need_define:
2462                 command_print(CMD_CTX,
2463                         "Please define bank %d via command: flash bank %s ... ",
2464                         x,
2465                         at91sam4_flash.name);
2466                 return ERROR_FAIL;
2467         }
2468
2469         /* if bank 0 is not probed, then probe it */
2470         if (!(pChip->details.bank[0].probed)) {
2471                 r = sam4_auto_probe(pChip->details.bank[0].pBank);
2472                 if (r != ERROR_OK)
2473                         return ERROR_FAIL;
2474         }
2475         /* above guarantees the "chip details" structure is valid */
2476         /* and thus, bank private areas are valid */
2477         /* and we have a SAM4 chip, what a concept! */
2478
2479         /* auto-probe other banks, 0 done above */
2480         for (x = 1; x < SAM4_MAX_FLASH_BANKS; x++) {
2481                 /* skip banks not present */
2482                 if (!(pChip->details.bank[x].present))
2483                         continue;
2484
2485                 if (pChip->details.bank[x].pBank == NULL)
2486                         goto need_define;
2487
2488                 if (pChip->details.bank[x].probed)
2489                         continue;
2490
2491                 r = sam4_auto_probe(pChip->details.bank[x].pBank);
2492                 if (r != ERROR_OK)
2493                         return r;
2494         }
2495
2496         r = sam4_GetInfo(pChip);
2497         if (r != ERROR_OK) {
2498                 LOG_DEBUG("Sam4Info, Failed %d", r);
2499                 return r;
2500         }
2501
2502         return ERROR_OK;
2503 }
2504
2505 COMMAND_HANDLER(sam4_handle_gpnvm_command)
2506 {
2507         unsigned x, v;
2508         int r, who;
2509         struct sam4_chip *pChip;
2510
2511         pChip = get_current_sam4(CMD_CTX);
2512         if (!pChip)
2513                 return ERROR_OK;
2514
2515         if (pChip->target->state != TARGET_HALTED) {
2516                 LOG_ERROR("sam4 - target not halted");
2517                 return ERROR_TARGET_NOT_HALTED;
2518         }
2519
2520         if (pChip->details.bank[0].pBank == NULL) {
2521                 command_print(CMD_CTX, "Bank0 must be defined first via: flash bank %s ...",
2522                         at91sam4_flash.name);
2523                 return ERROR_FAIL;
2524         }
2525         if (!pChip->details.bank[0].probed) {
2526                 r = sam4_auto_probe(pChip->details.bank[0].pBank);
2527                 if (r != ERROR_OK)
2528                         return r;
2529         }
2530
2531         switch (CMD_ARGC) {
2532                 default:
2533                         return ERROR_COMMAND_SYNTAX_ERROR;
2534                         break;
2535                 case 0:
2536                         goto showall;
2537                         break;
2538                 case 1:
2539                         who = -1;
2540                         break;
2541                 case 2:
2542                         if ((0 == strcmp(CMD_ARGV[0], "show")) && (0 == strcmp(CMD_ARGV[1], "all")))
2543                                 who = -1;
2544                         else {
2545                                 uint32_t v32;
2546                                 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], v32);
2547                                 who = v32;
2548                         }
2549                         break;
2550         }
2551
2552         if (0 == strcmp("show", CMD_ARGV[0])) {
2553                 if (who == -1) {
2554 showall:
2555                         r = ERROR_OK;
2556                         for (x = 0; x < pChip->details.n_gpnvms; x++) {
2557                                 r = FLASHD_GetGPNVM(&(pChip->details.bank[0]), x, &v);
2558                                 if (r != ERROR_OK)
2559                                         break;
2560                                 command_print(CMD_CTX, "sam4-gpnvm%u: %u", x, v);
2561                         }
2562                         return r;
2563                 }
2564                 if ((who >= 0) && (((unsigned)(who)) < pChip->details.n_gpnvms)) {
2565                         r = FLASHD_GetGPNVM(&(pChip->details.bank[0]), who, &v);
2566                         command_print(CMD_CTX, "sam4-gpnvm%u: %u", who, v);
2567                         return r;
2568                 } else {
2569                         command_print(CMD_CTX, "sam4-gpnvm invalid GPNVM: %u", who);
2570                         return ERROR_COMMAND_SYNTAX_ERROR;
2571                 }
2572         }
2573
2574         if (who == -1) {
2575                 command_print(CMD_CTX, "Missing GPNVM number");
2576                 return ERROR_COMMAND_SYNTAX_ERROR;
2577         }
2578
2579         if (0 == strcmp("set", CMD_ARGV[0]))
2580                 r = FLASHD_SetGPNVM(&(pChip->details.bank[0]), who);
2581         else if ((0 == strcmp("clr", CMD_ARGV[0])) ||
2582                  (0 == strcmp("clear", CMD_ARGV[0])))                   /* quietly accept both */
2583                 r = FLASHD_ClrGPNVM(&(pChip->details.bank[0]), who);
2584         else {
2585                 command_print(CMD_CTX, "Unknown command: %s", CMD_ARGV[0]);
2586                 r = ERROR_COMMAND_SYNTAX_ERROR;
2587         }
2588         return r;
2589 }
2590
2591 COMMAND_HANDLER(sam4_handle_slowclk_command)
2592 {
2593         struct sam4_chip *pChip;
2594
2595         pChip = get_current_sam4(CMD_CTX);
2596         if (!pChip)
2597                 return ERROR_OK;
2598
2599         switch (CMD_ARGC) {
2600                 case 0:
2601                         /* show */
2602                         break;
2603                 case 1:
2604                 {
2605                         /* set */
2606                         uint32_t v;
2607                         COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], v);
2608                         if (v > 200000) {
2609                                 /* absurd slow clock of 200Khz? */
2610                                 command_print(CMD_CTX, "Absurd/illegal slow clock freq: %d\n", (int)(v));
2611                                 return ERROR_COMMAND_SYNTAX_ERROR;
2612                         }
2613                         pChip->cfg.slow_freq = v;
2614                         break;
2615                 }
2616                 default:
2617                         /* error */
2618                         command_print(CMD_CTX, "Too many parameters");
2619                         return ERROR_COMMAND_SYNTAX_ERROR;
2620                         break;
2621         }
2622         command_print(CMD_CTX, "Slowclk freq: %d.%03dkhz",
2623                 (int)(pChip->cfg.slow_freq / 1000),
2624                 (int)(pChip->cfg.slow_freq % 1000));
2625         return ERROR_OK;
2626 }
2627
2628 static const struct command_registration at91sam4_exec_command_handlers[] = {
2629         {
2630                 .name = "gpnvm",
2631                 .handler = sam4_handle_gpnvm_command,
2632                 .mode = COMMAND_EXEC,
2633                 .usage = "[('clr'|'set'|'show') bitnum]",
2634                 .help = "Without arguments, shows all bits in the gpnvm "
2635                         "register.  Otherwise, clears, sets, or shows one "
2636                         "General Purpose Non-Volatile Memory (gpnvm) bit.",
2637         },
2638         {
2639                 .name = "info",
2640                 .handler = sam4_handle_info_command,
2641                 .mode = COMMAND_EXEC,
2642                 .help = "Print information about the current at91sam4 chip"
2643                         "and its flash configuration.",
2644         },
2645         {
2646                 .name = "slowclk",
2647                 .handler = sam4_handle_slowclk_command,
2648                 .mode = COMMAND_EXEC,
2649                 .usage = "[clock_hz]",
2650                 .help = "Display or set the slowclock frequency "
2651                         "(default 32768 Hz).",
2652         },
2653         COMMAND_REGISTRATION_DONE
2654 };
2655 static const struct command_registration at91sam4_command_handlers[] = {
2656         {
2657                 .name = "at91sam4",
2658                 .mode = COMMAND_ANY,
2659                 .help = "at91sam4 flash command group",
2660                 .usage = "",
2661                 .chain = at91sam4_exec_command_handlers,
2662         },
2663         COMMAND_REGISTRATION_DONE
2664 };
2665
2666 struct flash_driver at91sam4_flash = {
2667         .name = "at91sam4",
2668         .commands = at91sam4_command_handlers,
2669         .flash_bank_command = sam4_flash_bank_command,
2670         .erase = sam4_erase,
2671         .protect = sam4_protect,
2672         .write = sam4_write,
2673         .read = default_flash_read,
2674         .probe = sam4_probe,
2675         .auto_probe = sam4_auto_probe,
2676         .erase_check = default_flash_blank_check,
2677         .protect_check = sam4_protect_check,
2678 };