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