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