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