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