at91sam7: fix warnings by removing dead assignments
[fw/openocd] / src / flash / nor / at91sam7.c
1 /***************************************************************************
2  *   Copyright (C) 2006 by Magnus Lundin                                   *
3  *   lundin@mlu.mine.nu                                                    *
4  *                                                                         *
5  *   Copyright (C) 2008 by Gheorghe Guran (atlas)                          *
6  *                                                                         *
7  *   This program is free software; you can redistribute it and/or modify  *
8  *   it under the terms of the GNU General public License as published by  *
9  *   the Free Software Foundation; either version 2 of the License, or     *
10  *   (at your option) any later version.                                   *
11  *                                                                         *
12  *   This program is distributed in the hope that it will be useful,       *
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
14  *   MERCHANTABILITY or FITNESS for A PARTICULAR PURPOSE.  See the         *
15  *   GNU General public License for more details.                          *
16  *                                                                         *
17  *   You should have received a copy of the GNU General public License     *
18  *   along with this program; if not, write to the                         *
19  *   Free Software Foundation, Inc.,                                       *
20  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
21 ****************************************************************************/
22
23 /***************************************************************************
24 *
25 * New flash setup command:
26 *
27 * flash bank <driver> <base_addr> <size> <chip_width> <bus_width> <target_id>
28 *       [<chip_type> <banks>
29 *        <sectors_per_bank> <pages_per_sector>
30 *        <page_size> <num_nvmbits>
31 *        <ext_freq_khz>]
32 *
33 *   <ext_freq_khz> - MUST be used if clock is from external source,
34 *                    CAN be used if main oscillator frequency is known (recommended)
35 * Examples:
36 * ==== RECOMMENDED (covers clock speed) ============
37 *  flash bank at91sam7 0x00100000 0 0 4 $_TARGETNAME AT91SAM7XC256 1 16 64 256 3 25000
38 *                       (if auto-detect fails; provides clock spec)
39 *  flash bank at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 25000
40 *                       (auto-detect everything except the clock)
41 * ==== NOT RECOMMENDED !!! (clock speed is not configured) ====
42 *  flash bank at91sam7 0x00100000 0 0 4 $_TARGETNAME AT91SAM7XC256 1 16 64 256 3 0
43 *                       (if auto-detect fails)
44 *  flash bank at91sam7 0 0 0 0 $_TARGETNAME
45 *                       (old style, auto-detect everything)
46 ****************************************************************************/
47
48 #ifdef HAVE_CONFIG_H
49 #include "config.h"
50 #endif
51
52 #include "imp.h"
53 #include <helper/binarybuffer.h>
54
55
56 /* AT91SAM7 control registers */
57 #define DBGU_CIDR                       0xFFFFF240
58 #define CKGR_MCFR                       0xFFFFFC24
59 #define CKGR_MOR                        0xFFFFFC20
60 #define CKGR_MCFR_MAINRDY       0x10000
61 #define CKGR_PLLR                       0xFFFFFC2c
62 #define CKGR_PLLR_DIV           0xff
63 #define CKGR_PLLR_MUL           0x07ff0000
64 #define PMC_MCKR                        0xFFFFFC30
65 #define PMC_MCKR_CSS            0x03
66 #define PMC_MCKR_PRES           0x1c
67
68 /* Flash Controller Commands */
69 #define WP              0x01
70 #define SLB             0x02
71 #define WPL             0x03
72 #define CLB             0x04
73 #define EA              0x08
74 #define SGPB    0x0B
75 #define CGPB    0x0D
76 #define SSB             0x0F
77
78 /* MC_FSR bit definitions */
79 #define MC_FSR_FRDY                     1
80 #define MC_FSR_EOL                      2
81
82 /* AT91SAM7 constants */
83 #define RC_FREQ                         32000
84
85 /* Flash timing modes */
86 #define FMR_TIMING_NONE         0
87 #define FMR_TIMING_NVBITS       1
88 #define FMR_TIMING_FLASH        2
89
90 /* Flash size constants */
91 #define FLASH_SIZE_8KB          1
92 #define FLASH_SIZE_16KB         2
93 #define FLASH_SIZE_32KB         3
94 #define FLASH_SIZE_64KB         5
95 #define FLASH_SIZE_128KB        7
96 #define FLASH_SIZE_256KB        9
97 #define FLASH_SIZE_512KB        10
98 #define FLASH_SIZE_1024KB       12
99 #define FLASH_SIZE_2048KB       14
100
101
102 static int at91sam7_protect_check(struct flash_bank *bank);
103 static int at91sam7_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count);
104
105 static uint32_t at91sam7_get_flash_status(struct target *target, int bank_number);
106 static void at91sam7_set_flash_mode(struct flash_bank *bank, int mode);
107 static uint32_t at91sam7_wait_status_busy(struct flash_bank *bank, uint32_t waitbits, int timeout);
108 static int at91sam7_flash_command(struct flash_bank *bank, uint8_t cmd, uint16_t pagen);
109
110 static uint32_t MC_FMR[4] = { 0xFFFFFF60, 0xFFFFFF70, 0xFFFFFF80, 0xFFFFFF90 };
111 static uint32_t MC_FCR[4] = { 0xFFFFFF64, 0xFFFFFF74, 0xFFFFFF84, 0xFFFFFF94 };
112 static uint32_t MC_FSR[4] = { 0xFFFFFF68, 0xFFFFFF78, 0xFFFFFF88, 0xFFFFFF98 };
113
114 static char * EPROC[8]= {"Unknown","ARM946-E","ARM7TDMI","Unknown","ARM920T","ARM926EJ-S","Unknown","Unknown"};
115
116 struct at91sam7_flash_bank
117 {
118         /* chip id register */
119         uint32_t cidr;
120         uint16_t cidr_ext;
121         uint16_t cidr_nvptyp;
122         uint16_t cidr_arch;
123         uint16_t cidr_sramsiz;
124         uint16_t cidr_nvpsiz;
125         uint16_t cidr_nvpsiz2;
126         uint16_t cidr_eproc;
127         uint16_t cidr_version;
128         const char *target_name;
129
130         /* flash auto-detection */
131         uint8_t  flash_autodetection;
132
133         /* flash geometry */
134         uint16_t pages_per_sector;
135         uint16_t pagesize;
136         uint16_t pages_in_lockregion;
137
138         /* nv memory bits */
139         uint16_t num_lockbits_on;
140         uint16_t lockbits;
141         uint16_t num_nvmbits;
142         uint16_t num_nvmbits_on;
143         uint16_t nvmbits;
144         uint8_t  securitybit;
145
146         /* 0: not init
147          * 1: fmcn for nvbits (1uS)
148          * 2: fmcn for flash (1.5uS) */
149         uint8_t  flashmode;
150
151         /* main clock status */
152         uint8_t  mck_valid;
153         uint32_t mck_freq;
154
155         /* external clock frequency */
156         uint32_t ext_freq;
157
158 };
159
160 #if 0
161 static long SRAMSIZ[16] = {
162         -1,
163         0x0400,         /*  1K */
164         0x0800,         /*  2K */
165         -1,
166         0x1c000,        /* 112K */
167         0x1000,         /*   4K */
168         0x14000,        /*  80K */
169         0x28000,        /* 160K */
170         0x2000,         /*   8K */
171         0x4000,         /*  16K */
172         0x8000,         /*  32K */
173         0x10000,        /*  64K */
174         0x20000,        /* 128K */
175         0x40000,        /* 256K */
176         0x18000,        /*  96K */
177         0x80000,        /* 512K */
178 };
179 #endif
180
181
182 static uint32_t at91sam7_get_flash_status(struct target *target, int bank_number)
183 {
184         uint32_t fsr;
185         target_read_u32(target, MC_FSR[bank_number], &fsr);
186
187         return fsr;
188 }
189
190 /* Read clock configuration and set at91sam7_info->mck_freq */
191 static void at91sam7_read_clock_info(struct flash_bank *bank)
192 {
193         struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
194         struct target *target = bank->target;
195         uint32_t mckr, mcfr, pllr, mor;
196         unsigned long tmp = 0, mainfreq;
197
198         /* Read Clock Generator Main Oscillator Register */
199         target_read_u32(target, CKGR_MOR, &mor);
200         /* Read Clock Generator Main Clock Frequency Register */
201         target_read_u32(target, CKGR_MCFR, &mcfr);
202         /* Read Master Clock Register*/
203         target_read_u32(target, PMC_MCKR, &mckr);
204         /* Read Clock Generator PLL Register  */
205         target_read_u32(target, CKGR_PLLR, &pllr);
206
207         at91sam7_info->mck_valid = 0;
208         at91sam7_info->mck_freq = 0;
209         switch (mckr & PMC_MCKR_CSS)
210         {
211                 case 0:                 /* Slow Clock */
212                         at91sam7_info->mck_valid = 1;
213                         tmp = RC_FREQ;
214                         break;
215
216                 case 1:                 /* Main Clock */
217                         if ((mcfr & CKGR_MCFR_MAINRDY) &&
218                                 (at91sam7_info->ext_freq == 0))
219                         {
220                                 at91sam7_info->mck_valid = 1;
221                                 tmp = RC_FREQ / 16ul * (mcfr & 0xffff);
222                         }
223                         else if (at91sam7_info->ext_freq != 0)
224                         {
225                                 at91sam7_info->mck_valid = 1;
226                                 tmp = at91sam7_info->ext_freq;
227                         }
228                         break;
229
230                 case 2:                 /* Reserved */
231                         break;
232
233                 case 3:                 /* PLL Clock */
234                         if ((mcfr & CKGR_MCFR_MAINRDY) &&
235                                 (at91sam7_info->ext_freq == 0))
236                         {
237                                 target_read_u32(target, CKGR_PLLR, &pllr);
238                                 if (!(pllr & CKGR_PLLR_DIV))
239                                         break; /* 0 Hz */
240                                 at91sam7_info->mck_valid = 1;
241                                 mainfreq = RC_FREQ / 16ul * (mcfr & 0xffff);
242                                 /* Integer arithmetic should have sufficient precision
243                                  * as long as PLL is properly configured. */
244                                 tmp = mainfreq / (pllr & CKGR_PLLR_DIV)*
245                                         (((pllr & CKGR_PLLR_MUL) >> 16) + 1);
246                         }
247                         else if ((at91sam7_info->ext_freq != 0) &&
248                                 ((pllr&CKGR_PLLR_DIV) != 0))
249                         {
250                                 at91sam7_info->mck_valid = 1;
251                                 tmp = at91sam7_info->ext_freq / (pllr&CKGR_PLLR_DIV)*
252                                         (((pllr & CKGR_PLLR_MUL) >> 16) + 1);
253                         }
254                         break;
255         }
256
257         /* Prescaler adjust */
258         if ((((mckr & PMC_MCKR_PRES) >> 2) == 7) || (tmp == 0))
259         {
260                 at91sam7_info->mck_valid = 0;
261                 at91sam7_info->mck_freq = 0;
262         }
263         else if (((mckr & PMC_MCKR_PRES) >> 2) != 0)
264                 at91sam7_info->mck_freq = tmp >> ((mckr & PMC_MCKR_PRES) >> 2);
265         else
266                 at91sam7_info->mck_freq = tmp;
267 }
268
269 /* Setup the timimg registers for nvbits or normal flash */
270 static void at91sam7_set_flash_mode(struct flash_bank *bank, int mode)
271 {
272         uint32_t fmr, fmcn = 0, fws = 0;
273         struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
274         struct target *target = bank->target;
275
276         if (mode && (mode != at91sam7_info->flashmode))
277         {
278                 /* Always round up (ceil) */
279                 if (mode == FMR_TIMING_NVBITS)
280                 {
281                         if (at91sam7_info->cidr_arch == 0x60)
282                         {
283                                 /* AT91SAM7A3 uses master clocks in 100 ns */
284                                 fmcn = (at91sam7_info->mck_freq/10000000ul) + 1;
285                         }
286                         else
287                         {
288                                 /* master clocks in 1uS for ARCH 0x7 types */
289                                 fmcn = (at91sam7_info->mck_freq/1000000ul) + 1;
290                         }
291                 }
292                 else if (mode == FMR_TIMING_FLASH)
293                 {
294                         /* main clocks in 1.5uS */
295                         fmcn = (at91sam7_info->mck_freq/1000000ul)+
296                                 (at91sam7_info->mck_freq/2000000ul) + 1;
297                 }
298
299                 /* hard overclocking */
300                 if (fmcn > 0xFF)
301                         fmcn = 0xFF;
302
303                 /* Only allow fmcn = 0 if clock period is > 30 us = 33kHz. */
304                 if (at91sam7_info->mck_freq <= 33333ul)
305                         fmcn = 0;
306                 /* Only allow fws = 0 if clock frequency is < 30 MHz. */
307                 if (at91sam7_info->mck_freq > 30000000ul)
308                         fws = 1;
309
310                 LOG_DEBUG("fmcn[%i]: %i", bank->bank_number, (int)(fmcn));
311                 fmr = fmcn << 16 | fws << 8;
312                 target_write_u32(target, MC_FMR[bank->bank_number], fmr);
313         }
314
315         at91sam7_info->flashmode = mode;
316 }
317
318 static uint32_t at91sam7_wait_status_busy(struct flash_bank *bank, uint32_t waitbits, int timeout)
319 {
320         uint32_t status;
321
322         while ((!((status = at91sam7_get_flash_status(bank->target, bank->bank_number)) & waitbits)) && (timeout-- > 0))
323         {
324                 LOG_DEBUG("status[%i]: 0x%" PRIx32 "", (int)bank->bank_number, status);
325                 alive_sleep(1);
326         }
327
328         LOG_DEBUG("status[%i]: 0x%" PRIx32 "", bank->bank_number, status);
329
330         if (status & 0x0C)
331         {
332                 LOG_ERROR("status register: 0x%" PRIx32 "", status);
333                 if (status & 0x4)
334                         LOG_ERROR("Lock Error Bit Detected, Operation Abort");
335                 if (status & 0x8)
336                         LOG_ERROR("Invalid command and/or bad keyword, Operation Abort");
337                 if (status & 0x10)
338                         LOG_ERROR("Security Bit Set, Operation Abort");
339         }
340
341         return status;
342 }
343
344 /* Send one command to the AT91SAM flash controller */
345 static int at91sam7_flash_command(struct flash_bank *bank, uint8_t cmd, uint16_t pagen)
346 {
347         uint32_t fcr;
348         struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
349         struct target *target = bank->target;
350
351         fcr = (0x5A << 24) | ((pagen&0x3FF) << 8) | cmd;
352         target_write_u32(target, MC_FCR[bank->bank_number], fcr);
353         LOG_DEBUG("Flash command: 0x%" PRIx32 ", flash bank: %i, page number: %u", fcr, bank->bank_number + 1, pagen);
354
355         if ((at91sam7_info->cidr_arch == 0x60) && ((cmd == SLB) | (cmd == CLB)))
356         {
357                 /* Lock bit manipulation on AT91SAM7A3 waits for FC_FSR bit 1, EOL */
358                 if (at91sam7_wait_status_busy(bank, MC_FSR_EOL, 10)&0x0C)
359                 {
360                         return ERROR_FLASH_OPERATION_FAILED;
361                 }
362                 return ERROR_OK;
363         }
364
365         if (at91sam7_wait_status_busy(bank, MC_FSR_FRDY, 10)&0x0C)
366         {
367                 return ERROR_FLASH_OPERATION_FAILED;
368         }
369
370         return ERROR_OK;
371 }
372
373 /* Read device id register, main clock frequency register and fill in driver info structure */
374 static int at91sam7_read_part_info(struct flash_bank *bank)
375 {
376         struct flash_bank *t_bank = bank;
377         struct at91sam7_flash_bank *at91sam7_info;
378         struct target *target = t_bank->target;
379
380         uint16_t bnk, sec;
381         uint16_t arch;
382         uint32_t cidr;
383         uint8_t banks_num = 0;
384         uint16_t num_nvmbits = 0;
385         uint16_t sectors_num = 0;
386         uint16_t pages_per_sector = 0;
387         uint16_t page_size = 0;
388         uint32_t ext_freq;
389         uint32_t bank_size;
390         uint32_t base_address = 0;
391         char *target_name_t = "Unknown";
392
393         at91sam7_info = t_bank->driver_priv;
394
395         if (at91sam7_info->cidr != 0)
396         {
397                 /* flash already configured, update clock and check for protected sectors */
398                 struct flash_bank *fb = bank;
399                 t_bank = fb;
400
401                 while (t_bank)
402                 {
403                         /* re-calculate master clock frequency */
404                         at91sam7_read_clock_info(t_bank);
405
406                         /* no timming */
407                         at91sam7_set_flash_mode(t_bank, FMR_TIMING_NONE);
408
409                         /* check protect state */
410                         at91sam7_protect_check(t_bank);
411
412                         t_bank = fb->next;
413                         fb = t_bank;
414                 }
415
416                 return ERROR_OK;
417         }
418
419         /* Read and parse chip identification register */
420         target_read_u32(target, DBGU_CIDR, &cidr);
421         if (cidr == 0)
422         {
423                 LOG_WARNING("Cannot identify target as an AT91SAM");
424                 return ERROR_FLASH_OPERATION_FAILED;
425         }
426
427         if (at91sam7_info->flash_autodetection == 0)
428         {
429                 /* banks and sectors are already created, based on data from input file */
430                 struct flash_bank *fb = bank;
431                 t_bank = fb;
432                 while (t_bank)
433                 {
434                         at91sam7_info = t_bank->driver_priv;
435
436                         at91sam7_info->cidr = cidr;
437                         at91sam7_info->cidr_ext = (cidr >> 31)&0x0001;
438                         at91sam7_info->cidr_nvptyp = (cidr >> 28)&0x0007;
439                         at91sam7_info->cidr_arch = (cidr >> 20)&0x00FF;
440                         at91sam7_info->cidr_sramsiz = (cidr >> 16)&0x000F;
441                         at91sam7_info->cidr_nvpsiz2 = (cidr >> 12)&0x000F;
442                         at91sam7_info->cidr_nvpsiz = (cidr >> 8)&0x000F;
443                         at91sam7_info->cidr_eproc = (cidr >> 5)&0x0007;
444                         at91sam7_info->cidr_version = cidr&0x001F;
445
446                         /* calculate master clock frequency */
447                         at91sam7_read_clock_info(t_bank);
448
449                         /* no timming */
450                         at91sam7_set_flash_mode(t_bank, FMR_TIMING_NONE);
451
452                         /* check protect state */
453                         at91sam7_protect_check(t_bank);
454
455                         t_bank = fb->next;
456                         fb = t_bank;
457                 }
458
459                 return ERROR_OK;
460         }
461
462         arch = (cidr >> 20)&0x00FF;
463
464         /* check flash size */
465         switch ((cidr >> 8)&0x000F)
466         {
467                 case FLASH_SIZE_8KB:
468                         break;
469
470                 case FLASH_SIZE_16KB:
471                         banks_num = 1;
472                         sectors_num = 8;
473                         pages_per_sector = 32;
474                         page_size  = 64;
475                         base_address = 0x00100000;
476                         if (arch == 0x70)
477                         {
478                                 num_nvmbits = 2;
479                                 target_name_t = "AT91SAM7S161/16";
480                         }
481                         break;
482
483                 case FLASH_SIZE_32KB:
484                         banks_num = 1;
485                         sectors_num = 8;
486                         pages_per_sector = 32;
487                         page_size  = 128;
488                         base_address = 0x00100000;
489                         if (arch == 0x70)
490                         {
491                                 num_nvmbits = 2;
492                                 target_name_t = "AT91SAM7S321/32";
493                         }
494                         if (arch == 0x72)
495                         {
496                                 num_nvmbits = 3;
497                                 target_name_t = "AT91SAM7SE32";
498                         }
499                         break;
500
501                 case FLASH_SIZE_64KB:
502                         banks_num = 1;
503                         sectors_num = 16;
504                         pages_per_sector = 32;
505                         page_size  = 128;
506                         base_address = 0x00100000;
507                         if (arch == 0x70)
508                         {
509                                 num_nvmbits = 2;
510                                 target_name_t = "AT91SAM7S64";
511                         }
512                         break;
513
514                 case FLASH_SIZE_128KB:
515                         banks_num = 1;
516                         sectors_num = 8;
517                         pages_per_sector = 64;
518                         page_size  = 256;
519                         base_address = 0x00100000;
520                         if (arch == 0x70)
521                         {
522                                 num_nvmbits = 2;
523                                 target_name_t = "AT91SAM7S128";
524                         }
525                         if (arch == 0x71)
526                         {
527                                 num_nvmbits = 3;
528                                 target_name_t = "AT91SAM7XC128";
529                         }
530                         if (arch == 0x72)
531                         {
532                                 num_nvmbits = 3;
533                                 target_name_t = "AT91SAM7SE128";
534                         }
535                         if (arch == 0x75)
536                         {
537                                 num_nvmbits = 3;
538                                 target_name_t = "AT91SAM7X128";
539                         }
540                         break;
541
542                 case FLASH_SIZE_256KB:
543                         banks_num = 1;
544                         sectors_num = 16;
545                         pages_per_sector = 64;
546                         page_size  = 256;
547                         base_address = 0x00100000;
548                         if (arch == 0x60)
549                         {
550                                 num_nvmbits = 3;
551                                 target_name_t = "AT91SAM7A3";
552                         }
553                         if (arch == 0x70)
554                         {
555                                 num_nvmbits = 2;
556                                 target_name_t = "AT91SAM7S256";
557                         }
558                         if (arch == 0x71)
559                         {
560                                 num_nvmbits = 3;
561                                 target_name_t = "AT91SAM7XC256";
562                         }
563                         if (arch == 0x72)
564                         {
565                                 num_nvmbits = 3;
566                                 target_name_t = "AT91SAM7SE256";
567                         }
568                         if (arch == 0x75)
569                         {
570                                 num_nvmbits = 3;
571                                 target_name_t = "AT91SAM7X256";
572                         }
573                         break;
574
575                 case FLASH_SIZE_512KB:
576                         banks_num = 2;
577                         sectors_num = 16;
578                         pages_per_sector = 64;
579                         page_size  = 256;
580                         base_address = 0x00100000;
581                         if (arch == 0x70)
582                         {
583                                 num_nvmbits = 2;
584                                 target_name_t = "AT91SAM7S512";
585                         }
586                         if (arch == 0x71)
587                         {
588                                 num_nvmbits = 3;
589                                 target_name_t = "AT91SAM7XC512";
590                         }
591                         if (arch == 0x72)
592                         {
593                                 num_nvmbits = 3;
594                                 target_name_t = "AT91SAM7SE512";
595                         }
596                         if (arch == 0x75)
597                         {
598                                 num_nvmbits = 3;
599                                 target_name_t = "AT91SAM7X512";
600                         }
601                         break;
602
603                 case FLASH_SIZE_1024KB:
604                         break;
605
606                 case FLASH_SIZE_2048KB:
607                         break;
608         }
609
610         if (strcmp(target_name_t, "Unknown") == 0)
611         {
612                 LOG_ERROR("Target autodetection failed! Please specify target parameters in configuration file");
613                 return ERROR_FLASH_OPERATION_FAILED;
614         }
615
616         ext_freq = at91sam7_info->ext_freq;
617
618         /* calculate bank size  */
619         bank_size = sectors_num * pages_per_sector * page_size;
620
621         for (bnk = 0; bnk < banks_num; bnk++)
622         {
623                 if (bnk > 0)
624                 {
625                         /* create a new flash bank element */
626                         struct flash_bank *fb = malloc(sizeof(struct flash_bank));
627                         fb->target = target;
628                         fb->driver = bank->driver;
629                         fb->driver_priv = malloc(sizeof(struct at91sam7_flash_bank));
630                         fb->next = NULL;
631
632                         /* link created bank in 'flash_banks' list and redirect t_bank */
633                         t_bank->next = fb;
634                         t_bank = fb;
635                 }
636
637                 t_bank->bank_number = bnk;
638                 t_bank->base = base_address + bnk * bank_size;
639                 t_bank->size = bank_size;
640                 t_bank->chip_width = 0;
641                 t_bank->bus_width = 4;
642                 t_bank->num_sectors = sectors_num;
643
644                 /* allocate sectors */
645                 t_bank->sectors = malloc(sectors_num * sizeof(struct flash_sector));
646                 for (sec = 0; sec < sectors_num; sec++)
647                 {
648                         t_bank->sectors[sec].offset = sec * pages_per_sector * page_size;
649                         t_bank->sectors[sec].size = pages_per_sector * page_size;
650                         t_bank->sectors[sec].is_erased = -1;
651                         t_bank->sectors[sec].is_protected = -1;
652                 }
653
654                 at91sam7_info = t_bank->driver_priv;
655
656                 at91sam7_info->cidr = cidr;
657                 at91sam7_info->cidr_ext = (cidr >> 31)&0x0001;
658                 at91sam7_info->cidr_nvptyp = (cidr >> 28)&0x0007;
659                 at91sam7_info->cidr_arch = (cidr >> 20)&0x00FF;
660                 at91sam7_info->cidr_sramsiz = (cidr >> 16)&0x000F;
661                 at91sam7_info->cidr_nvpsiz2 = (cidr >> 12)&0x000F;
662                 at91sam7_info->cidr_nvpsiz = (cidr >> 8)&0x000F;
663                 at91sam7_info->cidr_eproc = (cidr >> 5)&0x0007;
664                 at91sam7_info->cidr_version = cidr&0x001F;
665
666                 at91sam7_info->target_name  = target_name_t;
667                 at91sam7_info->flashmode = 0;
668                 at91sam7_info->ext_freq = ext_freq;
669                 at91sam7_info->num_nvmbits = num_nvmbits;
670                 at91sam7_info->num_nvmbits_on = 0;
671                 at91sam7_info->pagesize = page_size;
672                 at91sam7_info->pages_per_sector = pages_per_sector;
673
674                 /* calculate master clock frequency */
675                 at91sam7_read_clock_info(t_bank);
676
677                 /* no timming */
678                 at91sam7_set_flash_mode(t_bank, FMR_TIMING_NONE);
679
680                 /* check protect state */
681                 at91sam7_protect_check(t_bank);
682         }
683
684         LOG_DEBUG("nvptyp: 0x%3.3x, arch: 0x%4.4x", at91sam7_info->cidr_nvptyp, at91sam7_info->cidr_arch);
685
686         return ERROR_OK;
687 }
688
689 static int at91sam7_erase_check(struct flash_bank *bank)
690 {
691         struct target *target = bank->target;
692         uint16_t retval;
693         uint32_t blank;
694         uint16_t fast_check;
695         uint8_t *buffer;
696         uint16_t nSector;
697         uint16_t nByte;
698
699         if (bank->target->state != TARGET_HALTED)
700         {
701                 LOG_ERROR("Target not halted");
702                 return ERROR_TARGET_NOT_HALTED;
703         }
704
705         /* Configure the flash controller timing */
706         at91sam7_read_clock_info(bank);
707         at91sam7_set_flash_mode(bank, FMR_TIMING_FLASH);
708
709         fast_check = 1;
710         for (nSector = 0; nSector < bank->num_sectors; nSector++)
711         {
712                 retval = target_blank_check_memory(target, bank->base + bank->sectors[nSector].offset,
713                         bank->sectors[nSector].size, &blank);
714                 if (retval != ERROR_OK)
715                 {
716                         fast_check = 0;
717                         break;
718                 }
719                 if (blank == 0xFF)
720                         bank->sectors[nSector].is_erased = 1;
721                 else
722                         bank->sectors[nSector].is_erased = 0;
723         }
724
725         if (fast_check)
726         {
727                 return ERROR_OK;
728         }
729
730         LOG_USER("Running slow fallback erase check - add working memory");
731
732         buffer = malloc(bank->sectors[0].size);
733         for (nSector = 0; nSector < bank->num_sectors; nSector++)
734         {
735                 bank->sectors[nSector].is_erased = 1;
736                 retval = target_read_memory(target, bank->base + bank->sectors[nSector].offset, 4,
737                         bank->sectors[nSector].size/4, buffer);
738                 if (retval != ERROR_OK)
739                         return retval;
740
741                 for (nByte = 0; nByte < bank->sectors[nSector].size; nByte++)
742                 {
743                         if (buffer[nByte] != 0xFF)
744                         {
745                                 bank->sectors[nSector].is_erased = 0;
746                                 break;
747                         }
748                 }
749         }
750         free(buffer);
751
752         return ERROR_OK;
753 }
754
755 static int at91sam7_protect_check(struct flash_bank *bank)
756 {
757         uint8_t lock_pos, gpnvm_pos;
758         uint32_t status;
759
760         struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
761
762         if (at91sam7_info->cidr == 0)
763         {
764                 return ERROR_FLASH_BANK_NOT_PROBED;
765         }
766         if (bank->target->state != TARGET_HALTED)
767         {
768                 LOG_ERROR("Target not halted");
769                 return ERROR_TARGET_NOT_HALTED;
770         }
771
772         status = at91sam7_get_flash_status(bank->target, bank->bank_number);
773         at91sam7_info->lockbits = (status >> 16);
774
775         at91sam7_info->num_lockbits_on = 0;
776         for (lock_pos = 0; lock_pos < bank->num_sectors; lock_pos++)
777         {
778                 if (((status >> (16 + lock_pos))&(0x0001)) == 1)
779                 {
780                         at91sam7_info->num_lockbits_on++;
781                         bank->sectors[lock_pos].is_protected = 1;
782                 }
783                 else
784                         bank->sectors[lock_pos].is_protected = 0;
785         }
786
787         /* GPNVM and SECURITY bits apply only for MC_FSR of EFC0 */
788         status = at91sam7_get_flash_status(bank->target, 0);
789
790         at91sam7_info->securitybit = (status >> 4)&0x01;
791         at91sam7_info->nvmbits = (status >> 8)&0xFF;
792
793         at91sam7_info->num_nvmbits_on = 0;
794         for (gpnvm_pos = 0; gpnvm_pos < at91sam7_info->num_nvmbits; gpnvm_pos++)
795         {
796                 if (((status >> (8 + gpnvm_pos))&(0x01)) == 1)
797                 {
798                         at91sam7_info->num_nvmbits_on++;
799                 }
800         }
801
802         return ERROR_OK;
803 }
804
805 FLASH_BANK_COMMAND_HANDLER(at91sam7_flash_bank_command)
806 {
807         struct flash_bank *t_bank = bank;
808         struct at91sam7_flash_bank *at91sam7_info;
809         struct target *target = t_bank->target;
810
811         uint32_t base_address;
812         uint32_t bank_size;
813         uint32_t ext_freq = 0;
814
815         int chip_width;
816         int bus_width;
817         int banks_num;
818         int num_sectors;
819
820         uint16_t pages_per_sector;
821         uint16_t page_size;
822         uint16_t num_nvmbits;
823
824         char *target_name_t;
825
826         int bnk, sec;
827
828         at91sam7_info = malloc(sizeof(struct at91sam7_flash_bank));
829         t_bank->driver_priv = at91sam7_info;
830
831         /* part wasn't probed for info yet */
832         at91sam7_info->cidr = 0;
833         at91sam7_info->flashmode = 0;
834         at91sam7_info->ext_freq = 0;
835         at91sam7_info->flash_autodetection = 0;
836
837         if (CMD_ARGC < 13)
838         {
839                 at91sam7_info->flash_autodetection = 1;
840                 return ERROR_OK;
841         }
842
843         COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], base_address);
844
845         COMMAND_PARSE_NUMBER(int, CMD_ARGV[3], chip_width);
846         COMMAND_PARSE_NUMBER(int, CMD_ARGV[4], bus_width);
847
848         COMMAND_PARSE_NUMBER(int, CMD_ARGV[8], banks_num);
849         COMMAND_PARSE_NUMBER(int, CMD_ARGV[9], num_sectors);
850         COMMAND_PARSE_NUMBER(u16, CMD_ARGV[10], pages_per_sector);
851         COMMAND_PARSE_NUMBER(u16, CMD_ARGV[11], page_size);
852         COMMAND_PARSE_NUMBER(u16, CMD_ARGV[12], num_nvmbits);
853
854         if (CMD_ARGC == 14) {
855                 unsigned long freq;
856                 COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[13], freq);
857                 ext_freq = freq * 1000;
858                 at91sam7_info->ext_freq = ext_freq;
859         }
860
861         if ((bus_width == 0) || (banks_num == 0) || (num_sectors == 0) ||
862                 (pages_per_sector == 0) || (page_size == 0) || (num_nvmbits == 0))
863         {
864                 at91sam7_info->flash_autodetection = 1;
865                 return ERROR_OK;
866         }
867
868         target_name_t = calloc(strlen(CMD_ARGV[7]) + 1, sizeof(char));
869         strcpy(target_name_t, CMD_ARGV[7]);
870
871         /* calculate bank size  */
872         bank_size = num_sectors * pages_per_sector * page_size;
873
874         for (bnk = 0; bnk < banks_num; bnk++)
875         {
876                 if (bnk > 0)
877                 {
878                         /* create a new bank element */
879                         struct flash_bank *fb = malloc(sizeof(struct flash_bank));
880                         fb->target = target;
881                         fb->driver = bank->driver;
882                         fb->driver_priv = malloc(sizeof(struct at91sam7_flash_bank));
883                         fb->next = NULL;
884
885                         /* link created bank in 'flash_banks' list and redirect t_bank */
886                         t_bank->next = fb;
887                         t_bank = fb;
888                 }
889
890                 t_bank->bank_number = bnk;
891                 t_bank->base = base_address + bnk * bank_size;
892                 t_bank->size = bank_size;
893                 t_bank->chip_width = chip_width;
894                 t_bank->bus_width = bus_width;
895                 t_bank->num_sectors = num_sectors;
896
897                 /* allocate sectors */
898                 t_bank->sectors = malloc(num_sectors * sizeof(struct flash_sector));
899                 for (sec = 0; sec < num_sectors; sec++)
900                 {
901                         t_bank->sectors[sec].offset = sec * pages_per_sector * page_size;
902                         t_bank->sectors[sec].size = pages_per_sector * page_size;
903                         t_bank->sectors[sec].is_erased = -1;
904                         t_bank->sectors[sec].is_protected = -1;
905                 }
906
907                 at91sam7_info = t_bank->driver_priv;
908
909                 at91sam7_info->target_name  = target_name_t;
910                 at91sam7_info->flashmode = 0;
911                 at91sam7_info->ext_freq  = ext_freq;
912                 at91sam7_info->num_nvmbits = num_nvmbits;
913                 at91sam7_info->num_nvmbits_on = 0;
914                 at91sam7_info->pagesize = page_size;
915                 at91sam7_info->pages_per_sector = pages_per_sector;
916         }
917
918         return ERROR_OK;
919 }
920
921 static int at91sam7_erase(struct flash_bank *bank, int first, int last)
922 {
923         struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
924         int sec;
925         uint32_t nbytes, pos;
926         uint8_t *buffer;
927         uint8_t erase_all;
928
929         if (at91sam7_info->cidr == 0)
930         {
931                 return ERROR_FLASH_BANK_NOT_PROBED;
932         }
933
934         if (bank->target->state != TARGET_HALTED)
935         {
936                 LOG_ERROR("Target not halted");
937                 return ERROR_TARGET_NOT_HALTED;
938         }
939
940         if ((first < 0) || (last < first) || (last >= bank->num_sectors))
941         {
942                 return ERROR_FLASH_SECTOR_INVALID;
943         }
944
945         erase_all = 0;
946         if ((first == 0) && (last == (bank->num_sectors-1)))
947         {
948                 erase_all = 1;
949         }
950
951         /* Configure the flash controller timing */
952         at91sam7_read_clock_info(bank);
953         at91sam7_set_flash_mode(bank, FMR_TIMING_FLASH);
954
955         if (erase_all)
956         {
957                 if (at91sam7_flash_command(bank, EA, 0) != ERROR_OK)
958                 {
959                         return ERROR_FLASH_OPERATION_FAILED;
960                 }
961         }
962         else
963         {
964                 /* allocate and clean buffer  */
965                 nbytes = (last - first + 1) * bank->sectors[first].size;
966                 buffer = malloc(nbytes * sizeof(uint8_t));
967                 for (pos = 0; pos < nbytes; pos++)
968                 {
969                         buffer[pos] = 0xFF;
970                 }
971
972                 if (at91sam7_write(bank, buffer, bank->sectors[first].offset, nbytes) != ERROR_OK)
973                 {
974                         return ERROR_FLASH_OPERATION_FAILED;
975                 }
976
977                 free(buffer);
978         }
979
980         /* mark erased sectors */
981         for (sec = first; sec <= last; sec++)
982         {
983                 bank->sectors[sec].is_erased = 1;
984         }
985
986         return ERROR_OK;
987 }
988
989 static int at91sam7_protect(struct flash_bank *bank, int set, int first, int last)
990 {
991         uint32_t cmd;
992         int sector;
993         uint32_t pagen;
994
995         struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
996
997         if (at91sam7_info->cidr == 0)
998         {
999                 return ERROR_FLASH_BANK_NOT_PROBED;
1000         }
1001
1002         if (bank->target->state != TARGET_HALTED)
1003         {
1004                 LOG_ERROR("Target not halted");
1005                 return ERROR_TARGET_NOT_HALTED;
1006         }
1007
1008         if ((first < 0) || (last < first) || (last >= bank->num_sectors))
1009         {
1010                 return ERROR_FLASH_SECTOR_INVALID;
1011         }
1012
1013         /* Configure the flash controller timing */
1014         at91sam7_read_clock_info(bank);
1015         at91sam7_set_flash_mode(bank, FMR_TIMING_NVBITS);
1016
1017         for (sector = first; sector <= last; sector++)
1018         {
1019                 if (set)
1020                         cmd = SLB;
1021                 else
1022                         cmd = CLB;
1023
1024                 /* if we lock a page from one sector then entire sector will be locked, also,
1025                  * if we unlock a page from a locked sector, entire sector will be unlocked   */
1026                 pagen = sector * at91sam7_info->pages_per_sector;
1027
1028                 if (at91sam7_flash_command(bank, cmd, pagen) != ERROR_OK)
1029                 {
1030                         return ERROR_FLASH_OPERATION_FAILED;
1031                 }
1032         }
1033
1034         at91sam7_protect_check(bank);
1035
1036         return ERROR_OK;
1037 }
1038
1039 static int at91sam7_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
1040 {
1041         int retval;
1042         struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
1043         struct target *target = bank->target;
1044         uint32_t dst_min_alignment, wcount, bytes_remaining = count;
1045         uint32_t first_page, last_page, pagen, buffer_pos;
1046
1047         if (at91sam7_info->cidr == 0)
1048         {
1049                 return ERROR_FLASH_BANK_NOT_PROBED;
1050         }
1051
1052         if (bank->target->state != TARGET_HALTED)
1053         {
1054                 LOG_ERROR("Target not halted");
1055                 return ERROR_TARGET_NOT_HALTED;
1056         }
1057
1058         if (offset + count > bank->size)
1059                 return ERROR_FLASH_DST_OUT_OF_BANK;
1060
1061         dst_min_alignment = at91sam7_info->pagesize;
1062
1063         if (offset % dst_min_alignment)
1064         {
1065                 LOG_WARNING("offset 0x%" PRIx32 " breaks required alignment 0x%" PRIx32 "", offset, dst_min_alignment);
1066                 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
1067         }
1068
1069         if (at91sam7_info->cidr_arch == 0)
1070                 return ERROR_FLASH_BANK_NOT_PROBED;
1071
1072         first_page = offset/dst_min_alignment;
1073         last_page = DIV_ROUND_UP(offset + count, dst_min_alignment);
1074
1075         LOG_DEBUG("first_page: %i, last_page: %i, count %i", (int)first_page, (int)last_page, (int)count);
1076
1077         /* Configure the flash controller timing */
1078         at91sam7_read_clock_info(bank);
1079         at91sam7_set_flash_mode(bank, FMR_TIMING_FLASH);
1080
1081         for (pagen = first_page; pagen < last_page; pagen++)
1082         {
1083                 if (bytes_remaining < dst_min_alignment)
1084                         count = bytes_remaining;
1085                 else
1086                         count = dst_min_alignment;
1087                 bytes_remaining -= count;
1088
1089                 /* Write one block to the PageWriteBuffer */
1090                 buffer_pos = (pagen-first_page)*dst_min_alignment;
1091                 wcount = DIV_ROUND_UP(count,4);
1092                 if ((retval = target_write_memory(target, bank->base + pagen*dst_min_alignment, 4, wcount, buffer + buffer_pos)) != ERROR_OK)
1093                 {
1094                         return retval;
1095                 }
1096
1097                 /* Send Write Page command to Flash Controller */
1098                 if (at91sam7_flash_command(bank, WP, pagen) != ERROR_OK)
1099                 {
1100                         return ERROR_FLASH_OPERATION_FAILED;
1101                 }
1102                 LOG_DEBUG("Write flash bank:%i page number:%" PRIi32 "", bank->bank_number, pagen);
1103         }
1104
1105         return ERROR_OK;
1106 }
1107
1108 static int at91sam7_probe(struct flash_bank *bank)
1109 {
1110         /* we can't probe on an at91sam7
1111          * if this is an at91sam7, it has the configured flash */
1112         int retval;
1113
1114         if (bank->target->state != TARGET_HALTED)
1115         {
1116                 LOG_ERROR("Target not halted");
1117                 return ERROR_TARGET_NOT_HALTED;
1118         }
1119
1120         retval = at91sam7_read_part_info(bank);
1121         if (retval != ERROR_OK)
1122                 return retval;
1123
1124         return ERROR_OK;
1125 }
1126
1127 static int get_at91sam7_info(struct flash_bank *bank, char *buf, int buf_size)
1128 {
1129         int printed;
1130         struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
1131
1132         if (at91sam7_info->cidr == 0)
1133         {
1134                 return ERROR_FLASH_BANK_NOT_PROBED;
1135         }
1136
1137         printed = snprintf(buf, buf_size,
1138                 "\n at91sam7 driver information: Chip is %s\n",
1139                 at91sam7_info->target_name);
1140
1141         buf += printed;
1142         buf_size -= printed;
1143
1144         printed = snprintf(buf,
1145                            buf_size,
1146                            " Cidr: 0x%8.8" PRIx32 " | Arch: 0x%4.4x | Eproc: %s | Version: 0x%3.3x | Flashsize: 0x%8.8" PRIx32 "\n",
1147                            at91sam7_info->cidr,
1148                            at91sam7_info->cidr_arch,
1149                            EPROC[at91sam7_info->cidr_eproc],
1150                            at91sam7_info->cidr_version,
1151                            bank->size);
1152
1153         buf += printed;
1154         buf_size -= printed;
1155
1156         printed = snprintf(buf, buf_size,
1157                 " Master clock (estimated): %u KHz | External clock: %u KHz\n",
1158                 (unsigned)(at91sam7_info->mck_freq / 1000), (unsigned)(at91sam7_info->ext_freq / 1000));
1159
1160         buf += printed;
1161         buf_size -= printed;
1162
1163         printed = snprintf(buf, buf_size,
1164                 " Pagesize: %i bytes | Lockbits(%i): %i 0x%4.4x | Pages in lock region: %i \n",
1165                 at91sam7_info->pagesize, bank->num_sectors, at91sam7_info->num_lockbits_on,
1166                 at91sam7_info->lockbits, at91sam7_info->pages_per_sector*at91sam7_info->num_lockbits_on);
1167
1168         buf += printed;
1169         buf_size -= printed;
1170
1171         snprintf(buf, buf_size,
1172                 " Securitybit: %i | Nvmbits(%i): %i 0x%1.1x\n",
1173                 at91sam7_info->securitybit, at91sam7_info->num_nvmbits,
1174                 at91sam7_info->num_nvmbits_on, at91sam7_info->nvmbits);
1175
1176         return ERROR_OK;
1177 }
1178
1179 /*
1180 * On AT91SAM7S: When the gpnvm bits are set with
1181 * > at91sam7 gpnvm bitnr set
1182 * the changes are not visible in the flash controller status register MC_FSR
1183 * until the processor has been reset.
1184 * On the Olimex board this requires a power cycle.
1185 * Note that the AT91SAM7S has the following errata (doc6175.pdf sec 14.1.3):
1186 *   The maximum number of write/erase cycles for Non volatile Memory bits is 100. this includes
1187 *   Lock Bits (LOCKx), General Purpose NVM bits (GPNVMx) and the Security Bit.
1188 */
1189 COMMAND_HANDLER(at91sam7_handle_gpnvm_command)
1190 {
1191         struct flash_bank *bank;
1192         int bit;
1193         uint8_t  flashcmd;
1194         uint32_t status;
1195         struct at91sam7_flash_bank *at91sam7_info;
1196         int retval;
1197
1198         if (CMD_ARGC != 2)
1199         {
1200                 command_print(CMD_CTX, "at91sam7 gpnvm <bit> <set | clear>");
1201                 return ERROR_OK;
1202         }
1203
1204         bank = get_flash_bank_by_num_noprobe(0);
1205         if (bank ==  NULL)
1206         {
1207                 return ERROR_FLASH_BANK_INVALID;
1208         }
1209         if (strcmp(bank->driver->name, "at91sam7"))
1210         {
1211                 command_print(CMD_CTX, "not an at91sam7 flash bank '%s'", CMD_ARGV[0]);
1212                 return ERROR_FLASH_BANK_INVALID;
1213         }
1214         if (bank->target->state != TARGET_HALTED)
1215         {
1216                 LOG_ERROR("target has to be halted to perform flash operation");
1217                 return ERROR_TARGET_NOT_HALTED;
1218         }
1219
1220         if (strcmp(CMD_ARGV[1], "set") == 0)
1221         {
1222                 flashcmd = SGPB;
1223         }
1224         else if (strcmp(CMD_ARGV[1], "clear") == 0)
1225         {
1226                 flashcmd = CGPB;
1227         }
1228         else
1229         {
1230                 return ERROR_COMMAND_SYNTAX_ERROR;
1231         }
1232
1233         at91sam7_info = bank->driver_priv;
1234         if (at91sam7_info->cidr == 0)
1235         {
1236                 retval = at91sam7_read_part_info(bank);
1237                 if (retval != ERROR_OK)
1238                 {
1239                         return retval;
1240                 }
1241         }
1242
1243         COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], bit);
1244         if ((bit < 0) || (bit >= at91sam7_info->num_nvmbits))
1245         {
1246                 command_print(CMD_CTX, "gpnvm bit '#%s' is out of bounds for target %s", CMD_ARGV[0], at91sam7_info->target_name);
1247                 return ERROR_OK;
1248         }
1249
1250         /* Configure the flash controller timing */
1251         at91sam7_read_clock_info(bank);
1252         at91sam7_set_flash_mode(bank, FMR_TIMING_NVBITS);
1253
1254         if (at91sam7_flash_command(bank, flashcmd, bit) != ERROR_OK)
1255         {
1256                 return ERROR_FLASH_OPERATION_FAILED;
1257         }
1258
1259         /* GPNVM and SECURITY bits apply only for MC_FSR of EFC0 */
1260         status = at91sam7_get_flash_status(bank->target, 0);
1261         LOG_DEBUG("at91sam7_handle_gpnvm_command: cmd 0x%x, value %d, status 0x%" PRIx32, flashcmd, bit, status);
1262
1263         /* check protect state */
1264         at91sam7_protect_check(bank);
1265
1266         return ERROR_OK;
1267 }
1268
1269 static const struct command_registration at91sam7_exec_command_handlers[] = {
1270         {
1271                 .name = "gpnvm",
1272                 .handler = at91sam7_handle_gpnvm_command,
1273                 .mode = COMMAND_EXEC,
1274                 .help = "set or clear one General Purpose Non-Volatile Memory "
1275                         "(gpnvm) bit",
1276                 .usage = "bitnum ('set'|'clear')",
1277         },
1278         COMMAND_REGISTRATION_DONE
1279 };
1280 static const struct command_registration at91sam7_command_handlers[] = {
1281         {
1282                 .name = "at91sam7",
1283                 .mode = COMMAND_ANY,
1284                 .help = "at91sam7 flash command group",
1285                 .chain = at91sam7_exec_command_handlers,
1286         },
1287         COMMAND_REGISTRATION_DONE
1288 };
1289
1290 struct flash_driver at91sam7_flash = {
1291         .name = "at91sam7",
1292         .commands = at91sam7_command_handlers,
1293         .flash_bank_command = at91sam7_flash_bank_command,
1294         .erase = at91sam7_erase,
1295         .protect = at91sam7_protect,
1296         .write = at91sam7_write,
1297         .read = default_flash_read,
1298         .probe = at91sam7_probe,
1299         .auto_probe = at91sam7_probe,
1300         .erase_check = at91sam7_erase_check,
1301         .protect_check = at91sam7_protect_check,
1302         .info = get_at91sam7_info,
1303 };