update files to correct FSF address
[fw/openocd] / src / flash / nor / str9xpec.c
1 /***************************************************************************
2  *   Copyright (C) 2005 by Dominic Rath                                    *
3  *   Dominic.Rath@gmx.de                                                   *
4  *                                                                         *
5  *   Copyright (C) 2008 by Spencer Oliver                                  *
6  *   spen@spen-soft.co.uk                                                  *
7  *                                                                         *
8  *   This program is free software; you can redistribute it and/or modify  *
9  *   it under the terms of the GNU General Public License as published by  *
10  *   the Free Software Foundation; either version 2 of the License, or     *
11  *   (at your option) any later version.                                   *
12  *                                                                         *
13  *   This program is distributed in the hope that it will be useful,       *
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
16  *   GNU General Public License for more details.                          *
17  *                                                                         *
18  *   You should have received a copy of the GNU General Public License     *
19  *   along with this program; if not, write to the                         *
20  *   Free Software Foundation, Inc.,                                       *
21  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
22  ***************************************************************************/
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include "imp.h"
29 #include <target/arm7_9_common.h>
30
31 /* ISC commands */
32
33 #define ISC_IDCODE                              0xFE
34 #define ISC_MFG_READ                    0x4C
35 #define ISC_CONFIGURATION               0x07
36 #define ISC_ENABLE                              0x0C
37 #define ISC_DISABLE                             0x0F
38 #define ISC_NOOP                                0x10
39 #define ISC_ADDRESS_SHIFT               0x11
40 #define ISC_CLR_STATUS                  0x13
41 #define ISC_PROGRAM                             0x20
42 #define ISC_PROGRAM_SECURITY    0x22
43 #define ISC_PROGRAM_UC                  0x23
44 #define ISC_ERASE                               0x30
45 #define ISC_READ                                0x50
46 #define ISC_BLANK_CHECK                 0x60
47
48 /* ISC_DEFAULT bit definitions */
49
50 #define ISC_STATUS_SECURITY             0x40
51 #define ISC_STATUS_INT_ERROR    0x30
52 #define ISC_STATUS_MODE                 0x08
53 #define ISC_STATUS_BUSY                 0x04
54 #define ISC_STATUS_ERROR                0x03
55
56 /* Option bytes definitions */
57
58 #define STR9XPEC_OPT_CSMAPBIT           48
59 #define STR9XPEC_OPT_LVDTHRESBIT        49
60 #define STR9XPEC_OPT_LVDSELBIT          50
61 #define STR9XPEC_OPT_LVDWARNBIT         51
62 #define STR9XPEC_OPT_OTPBIT                     63
63
64 enum str9xpec_status_codes {
65         STR9XPEC_INVALID_COMMAND = 1,
66         STR9XPEC_ISC_SUCCESS = 2,
67         STR9XPEC_ISC_DISABLED = 3,
68         STR9XPEC_ISC_INTFAIL = 32,
69 };
70
71 struct str9xpec_flash_controller {
72         struct jtag_tap *tap;
73         uint32_t *sector_bits;
74         int chain_pos;
75         int isc_enable;
76         uint8_t options[8];
77 };
78
79 static int str9xpec_erase_area(struct flash_bank *bank, int first, int last);
80 static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector);
81 static int str9xpec_write_options(struct flash_bank *bank);
82
83 static int str9xpec_set_instr(struct jtag_tap *tap, uint32_t new_instr, tap_state_t end_state)
84 {
85         if (tap == NULL)
86                 return ERROR_TARGET_INVALID;
87
88         if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) {
89                 struct scan_field field;
90
91                 field.num_bits = tap->ir_length;
92                 void *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);
93                 field.out_value = t;
94                 buf_set_u32(t, 0, field.num_bits, new_instr);
95                 field.in_value = NULL;
96
97                 jtag_add_ir_scan(tap, &field, end_state);
98
99                 free(t);
100         }
101
102         return ERROR_OK;
103 }
104
105 static uint8_t str9xpec_isc_status(struct jtag_tap *tap)
106 {
107         struct scan_field field;
108         uint8_t status;
109
110         if (str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE) != ERROR_OK)
111                 return ISC_STATUS_ERROR;
112
113         field.num_bits = 8;
114         field.out_value = NULL;
115         field.in_value = &status;
116
117
118         jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
119         jtag_execute_queue();
120
121         LOG_DEBUG("status: 0x%2.2x", status);
122
123         if (status & ISC_STATUS_SECURITY)
124                 LOG_INFO("Device Security Bit Set");
125
126         return status;
127 }
128
129 static int str9xpec_isc_enable(struct flash_bank *bank)
130 {
131         uint8_t status;
132         struct jtag_tap *tap;
133         struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
134
135         tap = str9xpec_info->tap;
136
137         if (str9xpec_info->isc_enable)
138                 return ERROR_OK;
139
140         /* enter isc mode */
141         if (str9xpec_set_instr(tap, ISC_ENABLE, TAP_IDLE) != ERROR_OK)
142                 return ERROR_TARGET_INVALID;
143
144         /* check ISC status */
145         status = str9xpec_isc_status(tap);
146         if (status & ISC_STATUS_MODE) {
147                 /* we have entered isc mode */
148                 str9xpec_info->isc_enable = 1;
149                 LOG_DEBUG("ISC_MODE Enabled");
150         }
151
152         return ERROR_OK;
153 }
154
155 static int str9xpec_isc_disable(struct flash_bank *bank)
156 {
157         uint8_t status;
158         struct jtag_tap *tap;
159         struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
160
161         tap = str9xpec_info->tap;
162
163         if (!str9xpec_info->isc_enable)
164                 return ERROR_OK;
165
166         if (str9xpec_set_instr(tap, ISC_DISABLE, TAP_IDLE) != ERROR_OK)
167                 return ERROR_TARGET_INVALID;
168
169         /* delay to handle aborts */
170         jtag_add_sleep(50);
171
172         /* check ISC status */
173         status = str9xpec_isc_status(tap);
174         if (!(status & ISC_STATUS_MODE)) {
175                 /* we have left isc mode */
176                 str9xpec_info->isc_enable = 0;
177                 LOG_DEBUG("ISC_MODE Disabled");
178         }
179
180         return ERROR_OK;
181 }
182
183 static int str9xpec_read_config(struct flash_bank *bank)
184 {
185         struct scan_field field;
186         uint8_t status;
187         struct jtag_tap *tap;
188
189         struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
190
191         tap = str9xpec_info->tap;
192
193         LOG_DEBUG("ISC_CONFIGURATION");
194
195         /* execute ISC_CONFIGURATION command */
196         str9xpec_set_instr(tap, ISC_CONFIGURATION, TAP_IRPAUSE);
197
198         field.num_bits = 64;
199         field.out_value = NULL;
200         field.in_value = str9xpec_info->options;
201
202         jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
203         jtag_execute_queue();
204
205         status = str9xpec_isc_status(tap);
206
207         return status;
208 }
209
210 static int str9xpec_build_block_list(struct flash_bank *bank)
211 {
212         struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
213
214         int i;
215         int num_sectors;
216         int b0_sectors = 0, b1_sectors = 0;
217         uint32_t offset = 0;
218         int b1_size = 0x2000;
219
220         switch (bank->size) {
221                 case (256 * 1024):
222                         b0_sectors = 4;
223                         break;
224                 case (512 * 1024):
225                         b0_sectors = 8;
226                         break;
227                 case (1024 * 1024):
228                         b0_sectors = 16;
229                         break;
230                 case (2048 * 1024):
231                         b0_sectors = 32;
232                         break;
233                 case (128 * 1024):
234                         b1_size = 0x4000;
235                         b1_sectors = 8;
236                         break;
237                 case (32 * 1024):
238                         b1_sectors = 4;
239                         break;
240                 default:
241                         LOG_ERROR("BUG: unknown bank->size encountered");
242                         exit(-1);
243         }
244
245         num_sectors = b0_sectors + b1_sectors;
246
247         bank->num_sectors = num_sectors;
248         bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);
249         str9xpec_info->sector_bits = malloc(sizeof(uint32_t) * num_sectors);
250
251         num_sectors = 0;
252
253         for (i = 0; i < b0_sectors; i++) {
254                 bank->sectors[num_sectors].offset = offset;
255                 bank->sectors[num_sectors].size = 0x10000;
256                 offset += bank->sectors[i].size;
257                 bank->sectors[num_sectors].is_erased = -1;
258                 bank->sectors[num_sectors].is_protected = 1;
259                 str9xpec_info->sector_bits[num_sectors++] = i;
260         }
261
262         for (i = 0; i < b1_sectors; i++) {
263                 bank->sectors[num_sectors].offset = offset;
264                 bank->sectors[num_sectors].size = b1_size;
265                 offset += bank->sectors[i].size;
266                 bank->sectors[num_sectors].is_erased = -1;
267                 bank->sectors[num_sectors].is_protected = 1;
268                 str9xpec_info->sector_bits[num_sectors++] = i + 32;
269         }
270
271         return ERROR_OK;
272 }
273
274 /* flash bank str9x <base> <size> 0 0 <target#>
275  */
276 FLASH_BANK_COMMAND_HANDLER(str9xpec_flash_bank_command)
277 {
278         struct str9xpec_flash_controller *str9xpec_info;
279         struct arm *arm = NULL;
280         struct arm7_9_common *arm7_9 = NULL;
281         struct arm_jtag *jtag_info = NULL;
282
283         if (CMD_ARGC < 6)
284                 return ERROR_COMMAND_SYNTAX_ERROR;
285
286         str9xpec_info = malloc(sizeof(struct str9xpec_flash_controller));
287         bank->driver_priv = str9xpec_info;
288
289         /* REVISIT verify that the jtag position of flash controller is
290          * right after *THIS* core, which must be a STR9xx core ...
291          */
292         arm = bank->target->arch_info;
293         arm7_9 = arm->arch_info;
294         jtag_info = &arm7_9->jtag_info;
295
296         /* The core is the next tap after the flash controller in the chain */
297         str9xpec_info->tap = jtag_tap_by_position(jtag_info->tap->abs_chain_position - 1);
298         str9xpec_info->isc_enable = 0;
299
300         str9xpec_build_block_list(bank);
301
302         /* clear option byte register */
303         buf_set_u32(str9xpec_info->options, 0, 64, 0);
304
305         return ERROR_OK;
306 }
307
308 static int str9xpec_blank_check(struct flash_bank *bank, int first, int last)
309 {
310         struct scan_field field;
311         uint8_t status;
312         struct jtag_tap *tap;
313         int i;
314         uint8_t *buffer = NULL;
315
316         struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
317
318         tap = str9xpec_info->tap;
319
320         if (!str9xpec_info->isc_enable)
321                 str9xpec_isc_enable(bank);
322
323         if (!str9xpec_info->isc_enable)
324                 return ERROR_FLASH_OPERATION_FAILED;
325
326         buffer = calloc(DIV_ROUND_UP(64, 8), 1);
327
328         LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first, last);
329
330         for (i = first; i <= last; i++)
331                 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
332
333         /* execute ISC_BLANK_CHECK command */
334         str9xpec_set_instr(tap, ISC_BLANK_CHECK, TAP_IRPAUSE);
335
336         field.num_bits = 64;
337         field.out_value = buffer;
338         field.in_value = NULL;
339
340         jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
341         jtag_add_sleep(40000);
342
343         /* read blank check result */
344         field.num_bits = 64;
345         field.out_value = NULL;
346         field.in_value = buffer;
347
348         jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
349         jtag_execute_queue();
350
351         status = str9xpec_isc_status(tap);
352
353         for (i = first; i <= last; i++) {
354                 if (buf_get_u32(buffer, str9xpec_info->sector_bits[i], 1))
355                         bank->sectors[i].is_erased = 0;
356                 else
357                         bank->sectors[i].is_erased = 1;
358         }
359
360         free(buffer);
361
362         str9xpec_isc_disable(bank);
363
364         if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
365                 return ERROR_FLASH_OPERATION_FAILED;
366         return ERROR_OK;
367 }
368
369 static int str9xpec_protect_check(struct flash_bank *bank)
370 {
371         uint8_t status;
372         int i;
373
374         struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
375
376         status = str9xpec_read_config(bank);
377
378         for (i = 0; i < bank->num_sectors; i++) {
379                 if (buf_get_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1))
380                         bank->sectors[i].is_protected = 1;
381                 else
382                         bank->sectors[i].is_protected = 0;
383         }
384
385         if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
386                 return ERROR_FLASH_OPERATION_FAILED;
387         return ERROR_OK;
388 }
389
390 static int str9xpec_erase_area(struct flash_bank *bank, int first, int last)
391 {
392         struct scan_field field;
393         uint8_t status;
394         struct jtag_tap *tap;
395         int i;
396         uint8_t *buffer = NULL;
397
398         struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
399
400         tap = str9xpec_info->tap;
401
402         if (!str9xpec_info->isc_enable)
403                 str9xpec_isc_enable(bank);
404
405         if (!str9xpec_info->isc_enable)
406                 return ISC_STATUS_ERROR;
407
408         buffer = calloc(DIV_ROUND_UP(64, 8), 1);
409
410         LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first, last);
411
412         /* last bank: 0xFF signals a full erase (unlock complete device) */
413         /* last bank: 0xFE signals a option byte erase */
414         if (last == 0xFF) {
415                 for (i = 0; i < 64; i++)
416                         buf_set_u32(buffer, i, 1, 1);
417         } else if (last == 0xFE)
418                 buf_set_u32(buffer, 49, 1, 1);
419         else {
420                 for (i = first; i <= last; i++)
421                         buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
422         }
423
424         LOG_DEBUG("ISC_ERASE");
425
426         /* execute ISC_ERASE command */
427         str9xpec_set_instr(tap, ISC_ERASE, TAP_IRPAUSE);
428
429         field.num_bits = 64;
430         field.out_value = buffer;
431         field.in_value = NULL;
432
433         jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
434         jtag_execute_queue();
435
436         jtag_add_sleep(10);
437
438         /* wait for erase completion */
439         while (!((status = str9xpec_isc_status(tap)) & ISC_STATUS_BUSY))
440                 alive_sleep(1);
441
442         free(buffer);
443
444         str9xpec_isc_disable(bank);
445
446         return status;
447 }
448
449 static int str9xpec_erase(struct flash_bank *bank, int first, int last)
450 {
451         int status;
452
453         status = str9xpec_erase_area(bank, first, last);
454
455         if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
456                 return ERROR_FLASH_OPERATION_FAILED;
457
458         return ERROR_OK;
459 }
460
461 static int str9xpec_lock_device(struct flash_bank *bank)
462 {
463         struct scan_field field;
464         uint8_t status;
465         struct jtag_tap *tap;
466         struct str9xpec_flash_controller *str9xpec_info = NULL;
467
468         str9xpec_info = bank->driver_priv;
469         tap = str9xpec_info->tap;
470
471         if (!str9xpec_info->isc_enable)
472                 str9xpec_isc_enable(bank);
473
474         if (!str9xpec_info->isc_enable)
475                 return ISC_STATUS_ERROR;
476
477         /* set security address */
478         str9xpec_set_address(bank, 0x80);
479
480         /* execute ISC_PROGRAM command */
481         str9xpec_set_instr(tap, ISC_PROGRAM_SECURITY, TAP_IDLE);
482
483         str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
484
485         do {
486                 field.num_bits = 8;
487                 field.out_value = NULL;
488                 field.in_value = &status;
489
490                 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
491                 jtag_execute_queue();
492
493         } while (!(status & ISC_STATUS_BUSY));
494
495         str9xpec_isc_disable(bank);
496
497         return status;
498 }
499
500 static int str9xpec_unlock_device(struct flash_bank *bank)
501 {
502         uint8_t status;
503
504         status = str9xpec_erase_area(bank, 0, 255);
505
506         return status;
507 }
508
509 static int str9xpec_protect(struct flash_bank *bank, int set, int first, int last)
510 {
511         uint8_t status;
512         int i;
513
514         struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
515
516         status = str9xpec_read_config(bank);
517
518         if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
519                 return ERROR_FLASH_OPERATION_FAILED;
520
521         LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first, last);
522
523         /* last bank: 0xFF signals a full device protect */
524         if (last == 0xFF) {
525                 if (set)
526                         status = str9xpec_lock_device(bank);
527                 else {
528                         /* perform full erase to unlock device */
529                         status = str9xpec_unlock_device(bank);
530                 }
531         } else {
532                 for (i = first; i <= last; i++) {
533                         if (set)
534                                 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 1);
535                         else
536                                 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 0);
537                 }
538
539                 status = str9xpec_write_options(bank);
540         }
541
542         if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
543                 return ERROR_FLASH_OPERATION_FAILED;
544
545         return ERROR_OK;
546 }
547
548 static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector)
549 {
550         struct jtag_tap *tap;
551         struct scan_field field;
552         struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
553
554         tap = str9xpec_info->tap;
555
556         /* set flash controller address */
557         str9xpec_set_instr(tap, ISC_ADDRESS_SHIFT, TAP_IRPAUSE);
558
559         field.num_bits = 8;
560         field.out_value = &sector;
561         field.in_value = NULL;
562
563         jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
564
565         return ERROR_OK;
566 }
567
568 static int str9xpec_write(struct flash_bank *bank, uint8_t *buffer,
569                 uint32_t offset, uint32_t count)
570 {
571         struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
572         uint32_t dwords_remaining = (count / 8);
573         uint32_t bytes_remaining = (count & 0x00000007);
574         uint32_t bytes_written = 0;
575         uint8_t status;
576         uint32_t check_address = offset;
577         struct jtag_tap *tap;
578         struct scan_field field;
579         uint8_t *scanbuf;
580         int i;
581         int first_sector = 0;
582         int last_sector = 0;
583
584         tap = str9xpec_info->tap;
585
586         if (!str9xpec_info->isc_enable)
587                 str9xpec_isc_enable(bank);
588
589         if (!str9xpec_info->isc_enable)
590                 return ERROR_FLASH_OPERATION_FAILED;
591
592         if (offset & 0x7) {
593                 LOG_WARNING("offset 0x%" PRIx32 " breaks required 8-byte alignment", offset);
594                 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
595         }
596
597         for (i = 0; i < bank->num_sectors; i++) {
598                 uint32_t sec_start = bank->sectors[i].offset;
599                 uint32_t sec_end = sec_start + bank->sectors[i].size;
600
601                 /* check if destination falls within the current sector */
602                 if ((check_address >= sec_start) && (check_address < sec_end)) {
603                         /* check if destination ends in the current sector */
604                         if (offset + count < sec_end)
605                                 check_address = offset + count;
606                         else
607                                 check_address = sec_end;
608                 }
609
610                 if ((offset >= sec_start) && (offset < sec_end))
611                         first_sector = i;
612
613                 if ((offset + count >= sec_start) && (offset + count < sec_end))
614                         last_sector = i;
615         }
616
617         if (check_address != offset + count)
618                 return ERROR_FLASH_DST_OUT_OF_BANK;
619
620         LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
621
622         scanbuf = calloc(DIV_ROUND_UP(64, 8), 1);
623
624         LOG_DEBUG("ISC_PROGRAM");
625
626         for (i = first_sector; i <= last_sector; i++) {
627                 str9xpec_set_address(bank, str9xpec_info->sector_bits[i]);
628
629                 dwords_remaining = dwords_remaining < (bank->sectors[i].size/8)
630                                 ? dwords_remaining : (bank->sectors[i].size/8);
631
632                 while (dwords_remaining > 0) {
633                         str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
634
635                         field.num_bits = 64;
636                         field.out_value = (buffer + bytes_written);
637                         field.in_value = NULL;
638
639                         jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
640
641                         /* small delay before polling */
642                         jtag_add_sleep(50);
643
644                         str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
645
646                         do {
647                                 field.num_bits = 8;
648                                 field.out_value = NULL;
649                                 field.in_value = scanbuf;
650
651                                 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
652                                 jtag_execute_queue();
653
654                                 status = buf_get_u32(scanbuf, 0, 8);
655
656                         } while (!(status & ISC_STATUS_BUSY));
657
658                         if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
659                                 return ERROR_FLASH_OPERATION_FAILED;
660
661                         /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
662                                 return ERROR_FLASH_OPERATION_FAILED; */
663
664                         dwords_remaining--;
665                         bytes_written += 8;
666                 }
667         }
668
669         if (bytes_remaining) {
670                 uint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
671
672                 /* copy the last remaining bytes into the write buffer */
673                 memcpy(last_dword, buffer+bytes_written, bytes_remaining);
674
675                 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
676
677                 field.num_bits = 64;
678                 field.out_value = last_dword;
679                 field.in_value = NULL;
680
681                 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
682
683                 /* small delay before polling */
684                 jtag_add_sleep(50);
685
686                 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
687
688                 do {
689                         field.num_bits = 8;
690                         field.out_value = NULL;
691                         field.in_value = scanbuf;
692
693                         jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
694                         jtag_execute_queue();
695
696                         status = buf_get_u32(scanbuf, 0, 8);
697
698                 } while (!(status & ISC_STATUS_BUSY));
699
700                 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
701                         return ERROR_FLASH_OPERATION_FAILED;
702
703                 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
704                         return ERROR_FLASH_OPERATION_FAILED; */
705         }
706
707         free(scanbuf);
708
709         str9xpec_isc_disable(bank);
710
711         return ERROR_OK;
712 }
713
714 static int str9xpec_probe(struct flash_bank *bank)
715 {
716         return ERROR_OK;
717 }
718
719 COMMAND_HANDLER(str9xpec_handle_part_id_command)
720 {
721         struct scan_field field;
722         uint8_t *buffer = NULL;
723         struct jtag_tap *tap;
724         uint32_t idcode;
725         struct str9xpec_flash_controller *str9xpec_info = NULL;
726
727         if (CMD_ARGC < 1)
728                 return ERROR_COMMAND_SYNTAX_ERROR;
729
730         struct flash_bank *bank;
731         int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
732         if (ERROR_OK != retval)
733                 return retval;
734
735         str9xpec_info = bank->driver_priv;
736         tap = str9xpec_info->tap;
737
738         buffer = calloc(DIV_ROUND_UP(32, 8), 1);
739
740         str9xpec_set_instr(tap, ISC_IDCODE, TAP_IRPAUSE);
741
742         field.num_bits = 32;
743         field.out_value = NULL;
744         field.in_value = buffer;
745
746         jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
747         jtag_execute_queue();
748
749         idcode = buf_get_u32(buffer, 0, 32);
750
751         command_print(CMD_CTX, "str9xpec part id: 0x%8.8" PRIx32 "", idcode);
752
753         free(buffer);
754
755         return ERROR_OK;
756 }
757
758 static int str9xpec_erase_check(struct flash_bank *bank)
759 {
760         return str9xpec_blank_check(bank, 0, bank->num_sectors - 1);
761 }
762
763 static int get_str9xpec_info(struct flash_bank *bank, char *buf, int buf_size)
764 {
765         snprintf(buf, buf_size, "str9xpec flash driver info");
766         return ERROR_OK;
767 }
768
769 COMMAND_HANDLER(str9xpec_handle_flash_options_read_command)
770 {
771         uint8_t status;
772         struct str9xpec_flash_controller *str9xpec_info = NULL;
773
774         if (CMD_ARGC < 1)
775                 return ERROR_COMMAND_SYNTAX_ERROR;
776
777         struct flash_bank *bank;
778         int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
779         if (ERROR_OK != retval)
780                 return retval;
781
782         str9xpec_info = bank->driver_priv;
783
784         status = str9xpec_read_config(bank);
785
786         if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
787                 return ERROR_FLASH_OPERATION_FAILED;
788
789         /* boot bank */
790         if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1))
791                 command_print(CMD_CTX, "CS Map: bank1");
792         else
793                 command_print(CMD_CTX, "CS Map: bank0");
794
795         /* OTP lock */
796         if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1))
797                 command_print(CMD_CTX, "OTP Lock: OTP Locked");
798         else
799                 command_print(CMD_CTX, "OTP Lock: OTP Unlocked");
800
801         /* LVD Threshold */
802         if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1))
803                 command_print(CMD_CTX, "LVD Threshold: 2.7v");
804         else
805                 command_print(CMD_CTX, "LVD Threshold: 2.4v");
806
807         /* LVD reset warning */
808         if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1))
809                 command_print(CMD_CTX, "LVD Reset Warning: VDD or VDDQ Inputs");
810         else
811                 command_print(CMD_CTX, "LVD Reset Warning: VDD Input Only");
812
813         /* LVD reset select */
814         if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1))
815                 command_print(CMD_CTX, "LVD Reset Selection: VDD or VDDQ Inputs");
816         else
817                 command_print(CMD_CTX, "LVD Reset Selection: VDD Input Only");
818
819         return ERROR_OK;
820 }
821
822 static int str9xpec_write_options(struct flash_bank *bank)
823 {
824         struct scan_field field;
825         uint8_t status;
826         struct jtag_tap *tap;
827         struct str9xpec_flash_controller *str9xpec_info = NULL;
828
829         str9xpec_info = bank->driver_priv;
830         tap = str9xpec_info->tap;
831
832         /* erase config options first */
833         status = str9xpec_erase_area(bank, 0xFE, 0xFE);
834
835         if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
836                 return status;
837
838         if (!str9xpec_info->isc_enable)
839                 str9xpec_isc_enable(bank);
840
841         if (!str9xpec_info->isc_enable)
842                 return ISC_STATUS_ERROR;
843
844         /* according to data 64th bit has to be set */
845         buf_set_u32(str9xpec_info->options, 63, 1, 1);
846
847         /* set option byte address */
848         str9xpec_set_address(bank, 0x50);
849
850         /* execute ISC_PROGRAM command */
851         str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
852
853         field.num_bits = 64;
854         field.out_value = str9xpec_info->options;
855         field.in_value = NULL;
856
857         jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
858
859         /* small delay before polling */
860         jtag_add_sleep(50);
861
862         str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
863
864         do {
865                 field.num_bits = 8;
866                 field.out_value = NULL;
867                 field.in_value = &status;
868
869                 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
870                 jtag_execute_queue();
871
872         } while (!(status & ISC_STATUS_BUSY));
873
874         str9xpec_isc_disable(bank);
875
876         return status;
877 }
878
879 COMMAND_HANDLER(str9xpec_handle_flash_options_write_command)
880 {
881         uint8_t status;
882
883         if (CMD_ARGC < 1)
884                 return ERROR_COMMAND_SYNTAX_ERROR;
885
886         struct flash_bank *bank;
887         int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
888         if (ERROR_OK != retval)
889                 return retval;
890
891         status = str9xpec_write_options(bank);
892
893         if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
894                 return ERROR_FLASH_OPERATION_FAILED;
895
896         command_print(CMD_CTX, "str9xpec write options complete.\n"
897                         "INFO: a reset or power cycle is required "
898                         "for the new settings to take effect.");
899
900         return ERROR_OK;
901 }
902
903 COMMAND_HANDLER(str9xpec_handle_flash_options_cmap_command)
904 {
905         struct str9xpec_flash_controller *str9xpec_info = NULL;
906
907         if (CMD_ARGC < 2)
908                 return ERROR_COMMAND_SYNTAX_ERROR;
909
910         struct flash_bank *bank;
911         int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
912         if (ERROR_OK != retval)
913                 return retval;
914
915         str9xpec_info = bank->driver_priv;
916
917         if (strcmp(CMD_ARGV[1], "bank1") == 0)
918                 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 1);
919         else
920                 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0);
921
922         return ERROR_OK;
923 }
924
925 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdthd_command)
926 {
927         struct str9xpec_flash_controller *str9xpec_info = NULL;
928
929         if (CMD_ARGC < 2)
930                 return ERROR_COMMAND_SYNTAX_ERROR;
931
932         struct flash_bank *bank;
933         int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
934         if (ERROR_OK != retval)
935                 return retval;
936
937         str9xpec_info = bank->driver_priv;
938
939         if (strcmp(CMD_ARGV[1], "2.7v") == 0)
940                 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 1);
941         else
942                 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0);
943
944         return ERROR_OK;
945 }
946
947 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdsel_command)
948 {
949         struct str9xpec_flash_controller *str9xpec_info = NULL;
950
951         if (CMD_ARGC < 2)
952                 return ERROR_COMMAND_SYNTAX_ERROR;
953
954         struct flash_bank *bank;
955         int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
956         if (ERROR_OK != retval)
957                 return retval;
958
959         str9xpec_info = bank->driver_priv;
960
961         if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0)
962                 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 1);
963         else
964                 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0);
965
966         return ERROR_OK;
967 }
968
969 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdwarn_command)
970 {
971         struct str9xpec_flash_controller *str9xpec_info = NULL;
972
973         if (CMD_ARGC < 2)
974                 return ERROR_COMMAND_SYNTAX_ERROR;
975
976         struct flash_bank *bank;
977         int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
978         if (ERROR_OK != retval)
979                 return retval;
980
981         str9xpec_info = bank->driver_priv;
982
983         if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0)
984                 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 1);
985         else
986                 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0);
987
988         return ERROR_OK;
989 }
990
991 COMMAND_HANDLER(str9xpec_handle_flash_lock_command)
992 {
993         uint8_t status;
994
995         if (CMD_ARGC < 1)
996                 return ERROR_COMMAND_SYNTAX_ERROR;
997
998         struct flash_bank *bank;
999         int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1000         if (ERROR_OK != retval)
1001                 return retval;
1002
1003         status = str9xpec_lock_device(bank);
1004
1005         if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1006                 return ERROR_FLASH_OPERATION_FAILED;
1007
1008         return ERROR_OK;
1009 }
1010
1011 COMMAND_HANDLER(str9xpec_handle_flash_unlock_command)
1012 {
1013         uint8_t status;
1014
1015         if (CMD_ARGC < 1)
1016                 return ERROR_COMMAND_SYNTAX_ERROR;
1017
1018         struct flash_bank *bank;
1019         int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1020         if (ERROR_OK != retval)
1021                 return retval;
1022
1023         status = str9xpec_unlock_device(bank);
1024
1025         if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1026                 return ERROR_FLASH_OPERATION_FAILED;
1027
1028         command_print(CMD_CTX, "str9xpec unlocked.\n"
1029                         "INFO: a reset or power cycle is required "
1030                         "for the new settings to take effect.");
1031
1032         return ERROR_OK;
1033 }
1034
1035 COMMAND_HANDLER(str9xpec_handle_flash_enable_turbo_command)
1036 {
1037         struct jtag_tap *tap0;
1038         struct jtag_tap *tap1;
1039         struct jtag_tap *tap2;
1040         struct str9xpec_flash_controller *str9xpec_info = NULL;
1041
1042         if (CMD_ARGC < 1)
1043                 return ERROR_COMMAND_SYNTAX_ERROR;
1044
1045         struct flash_bank *bank;
1046         int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1047         if (ERROR_OK != retval)
1048                 return retval;
1049
1050         str9xpec_info = bank->driver_priv;
1051
1052         /* remove arm core from chain - enter turbo mode */
1053         tap0 = str9xpec_info->tap;
1054         if (tap0 == NULL) {
1055                 /* things are *WRONG* */
1056                 command_print(CMD_CTX, "**STR9FLASH** (tap0) invalid chain?");
1057                 return ERROR_FAIL;
1058         }
1059         tap1 = tap0->next_tap;
1060         if (tap1 == NULL) {
1061                 /* things are *WRONG* */
1062                 command_print(CMD_CTX, "**STR9FLASH** (tap1) invalid chain?");
1063                 return ERROR_FAIL;
1064         }
1065         tap2 = tap1->next_tap;
1066         if (tap2 == NULL) {
1067                 /* things are *WRONG* */
1068                 command_print(CMD_CTX, "**STR9FLASH** (tap2) invalid chain?");
1069                 return ERROR_FAIL;
1070         }
1071
1072         /* enable turbo mode - TURBO-PROG-ENABLE */
1073         str9xpec_set_instr(tap2, 0xD, TAP_IDLE);
1074         retval = jtag_execute_queue();
1075         if (retval != ERROR_OK)
1076                 return retval;
1077
1078         /* modify scan chain - str9 core has been removed */
1079         tap1->enabled = 0;
1080
1081         return ERROR_OK;
1082 }
1083
1084 COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command)
1085 {
1086         struct jtag_tap *tap;
1087         struct str9xpec_flash_controller *str9xpec_info = NULL;
1088
1089         if (CMD_ARGC < 1)
1090                 return ERROR_COMMAND_SYNTAX_ERROR;
1091
1092         struct flash_bank *bank;
1093         int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1094         if (ERROR_OK != retval)
1095                 return retval;
1096
1097         str9xpec_info = bank->driver_priv;
1098         tap = str9xpec_info->tap;
1099
1100         if (tap == NULL)
1101                 return ERROR_FAIL;
1102
1103         /* exit turbo mode via RESET */
1104         str9xpec_set_instr(tap, ISC_NOOP, TAP_IDLE);
1105         jtag_add_tlr();
1106         jtag_execute_queue();
1107
1108         /* restore previous scan chain */
1109         if (tap->next_tap)
1110                 tap->next_tap->enabled = 1;
1111
1112         return ERROR_OK;
1113 }
1114
1115 static const struct command_registration str9xpec_config_command_handlers[] = {
1116         {
1117                 .name = "enable_turbo",
1118                 .usage = "<bank>",
1119                 .handler = str9xpec_handle_flash_enable_turbo_command,
1120                 .mode = COMMAND_EXEC,
1121                 .help = "enable str9xpec turbo mode",
1122         },
1123         {
1124                 .name = "disable_turbo",
1125                 .usage = "<bank>",
1126                 .handler = str9xpec_handle_flash_disable_turbo_command,
1127                 .mode = COMMAND_EXEC,
1128                 .help = "disable str9xpec turbo mode",
1129         },
1130         {
1131                 .name = "options_cmap",
1132                 .usage = "<bank> <bank0 | bank1>",
1133                 .handler = str9xpec_handle_flash_options_cmap_command,
1134                 .mode = COMMAND_EXEC,
1135                 .help = "configure str9xpec boot sector",
1136         },
1137         {
1138                 .name = "options_lvdthd",
1139                 .usage = "<bank> <2.4v | 2.7v>",
1140                 .handler = str9xpec_handle_flash_options_lvdthd_command,
1141                 .mode = COMMAND_EXEC,
1142                 .help = "configure str9xpec lvd threshold",
1143         },
1144         {
1145                 .name = "options_lvdsel",
1146                 .usage = "<bank> <vdd | vdd_vddq>",
1147                 .handler = str9xpec_handle_flash_options_lvdsel_command,
1148                 .mode = COMMAND_EXEC,
1149                 .help = "configure str9xpec lvd selection",
1150         },
1151         {
1152                 .name = "options_lvdwarn",
1153                 .usage = "<bank> <vdd | vdd_vddq>",
1154                 .handler = str9xpec_handle_flash_options_lvdwarn_command,
1155                 .mode = COMMAND_EXEC,
1156                 .help = "configure str9xpec lvd warning",
1157         },
1158         {
1159                 .name = "options_read",
1160                 .usage = "<bank>",
1161                 .handler = str9xpec_handle_flash_options_read_command,
1162                 .mode = COMMAND_EXEC,
1163                 .help = "read str9xpec options",
1164         },
1165         {
1166                 .name = "options_write",
1167                 .usage = "<bank>",
1168                 .handler = str9xpec_handle_flash_options_write_command,
1169                 .mode = COMMAND_EXEC,
1170                 .help = "write str9xpec options",
1171         },
1172         {
1173                 .name = "lock",
1174                 .usage = "<bank>",
1175                 .handler = str9xpec_handle_flash_lock_command,
1176                 .mode = COMMAND_EXEC,
1177                 .help = "lock str9xpec device",
1178         },
1179         {
1180                 .name = "unlock",
1181                 .usage = "<bank>",
1182                 .handler = str9xpec_handle_flash_unlock_command,
1183                 .mode = COMMAND_EXEC,
1184                 .help = "unlock str9xpec device",
1185         },
1186         {
1187                 .name = "part_id",
1188                 .handler = str9xpec_handle_part_id_command,
1189                 .mode = COMMAND_EXEC,
1190                 .help = "print part id of str9xpec flash bank <num>",
1191         },
1192         COMMAND_REGISTRATION_DONE
1193 };
1194
1195 static const struct command_registration str9xpec_command_handlers[] = {
1196         {
1197                 .name = "str9xpec",
1198                 .mode = COMMAND_ANY,
1199                 .help = "str9xpec flash command group",
1200                 .usage = "",
1201                 .chain = str9xpec_config_command_handlers,
1202         },
1203         COMMAND_REGISTRATION_DONE
1204 };
1205
1206 struct flash_driver str9xpec_flash = {
1207         .name = "str9xpec",
1208         .commands = str9xpec_command_handlers,
1209         .flash_bank_command = str9xpec_flash_bank_command,
1210         .erase = str9xpec_erase,
1211         .protect = str9xpec_protect,
1212         .write = str9xpec_write,
1213         .read = default_flash_read,
1214         .probe = str9xpec_probe,
1215         .auto_probe = str9xpec_probe,
1216         .erase_check = str9xpec_erase_check,
1217         .protect_check = str9xpec_protect_check,
1218         .info = get_str9xpec_info,
1219 };