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