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