str9xpec: -Wshadow warning fixes
[openocd/cortex.git] / src / flash / nor / str9xpec.c
blobf8b705e080c6c5aa057102e2cb9107a953be106b
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
27 #include "imp.h"
28 #include "str9xpec.h"
29 #include <target/arm7_9_common.h>
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);
36 static int str9xpec_set_instr(struct jtag_tap *tap, uint32_t new_instr, tap_state_t end_state)
38 if (tap == NULL) {
39 return ERROR_TARGET_INVALID;
42 if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr)
44 struct scan_field field;
46 field.num_bits = tap->ir_length;
47 void * t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);
48 field.out_value = t;
49 buf_set_u32(t, 0, field.num_bits, new_instr);
50 field.in_value = NULL;
52 jtag_add_ir_scan(tap, &field, end_state);
54 free(t);
57 return ERROR_OK;
60 static uint8_t str9xpec_isc_status(struct jtag_tap *tap)
62 struct scan_field field;
63 uint8_t status;
65 if (str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE) != ERROR_OK)
66 return ISC_STATUS_ERROR;
68 field.num_bits = 8;
69 field.out_value = NULL;
70 field.in_value = &status;
73 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
74 jtag_execute_queue();
76 LOG_DEBUG("status: 0x%2.2x", status);
78 if (status & ISC_STATUS_SECURITY)
79 LOG_INFO("Device Security Bit Set");
81 return status;
84 static int str9xpec_isc_enable(struct flash_bank *bank)
86 uint8_t status;
87 struct jtag_tap *tap;
88 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
90 tap = str9xpec_info->tap;
92 if (str9xpec_info->isc_enable)
93 return ERROR_OK;
95 /* enter isc mode */
96 if (str9xpec_set_instr(tap, ISC_ENABLE, TAP_IDLE) != ERROR_OK)
97 return ERROR_TARGET_INVALID;
99 /* check ISC status */
100 status = str9xpec_isc_status(tap);
101 if (status & ISC_STATUS_MODE)
103 /* we have entered isc mode */
104 str9xpec_info->isc_enable = 1;
105 LOG_DEBUG("ISC_MODE Enabled");
108 return ERROR_OK;
111 static int str9xpec_isc_disable(struct flash_bank *bank)
113 uint8_t status;
114 struct jtag_tap *tap;
115 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
117 tap = str9xpec_info->tap;
119 if (!str9xpec_info->isc_enable)
120 return ERROR_OK;
122 if (str9xpec_set_instr(tap, ISC_DISABLE, TAP_IDLE) != ERROR_OK)
123 return ERROR_TARGET_INVALID;
125 /* delay to handle aborts */
126 jtag_add_sleep(50);
128 /* check ISC status */
129 status = str9xpec_isc_status(tap);
130 if (!(status & ISC_STATUS_MODE))
132 /* we have left isc mode */
133 str9xpec_info->isc_enable = 0;
134 LOG_DEBUG("ISC_MODE Disabled");
137 return ERROR_OK;
140 static int str9xpec_read_config(struct flash_bank *bank)
142 struct scan_field field;
143 uint8_t status;
144 struct jtag_tap *tap;
146 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
148 tap = str9xpec_info->tap;
150 LOG_DEBUG("ISC_CONFIGURATION");
152 /* execute ISC_CONFIGURATION command */
153 str9xpec_set_instr(tap, ISC_CONFIGURATION, TAP_IRPAUSE);
155 field.num_bits = 64;
156 field.out_value = NULL;
157 field.in_value = str9xpec_info->options;
160 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
161 jtag_execute_queue();
163 status = str9xpec_isc_status(tap);
165 return status;
168 static int str9xpec_build_block_list(struct flash_bank *bank)
170 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
172 int i;
173 int num_sectors;
174 int b0_sectors = 0, b1_sectors = 0;
175 uint32_t offset = 0;
176 int b1_size = 0x2000;
178 switch (bank->size)
180 case (256 * 1024):
181 b0_sectors = 4;
182 break;
183 case (512 * 1024):
184 b0_sectors = 8;
185 break;
186 case (1024 * 1024):
187 b0_sectors = 16;
188 break;
189 case (2048 * 1024):
190 b0_sectors = 32;
191 break;
192 case (128 * 1024):
193 b1_size = 0x4000;
194 b1_sectors = 8;
195 break;
196 case (32 * 1024):
197 b1_sectors = 4;
198 break;
199 default:
200 LOG_ERROR("BUG: unknown bank->size encountered");
201 exit(-1);
204 num_sectors = b0_sectors + b1_sectors;
206 bank->num_sectors = num_sectors;
207 bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);
208 str9xpec_info->sector_bits = malloc(sizeof(uint32_t) * num_sectors);
210 num_sectors = 0;
212 for (i = 0; i < b0_sectors; i++)
214 bank->sectors[num_sectors].offset = offset;
215 bank->sectors[num_sectors].size = 0x10000;
216 offset += bank->sectors[i].size;
217 bank->sectors[num_sectors].is_erased = -1;
218 bank->sectors[num_sectors].is_protected = 1;
219 str9xpec_info->sector_bits[num_sectors++] = i;
222 for (i = 0; i < b1_sectors; i++)
224 bank->sectors[num_sectors].offset = offset;
225 bank->sectors[num_sectors].size = b1_size;
226 offset += bank->sectors[i].size;
227 bank->sectors[num_sectors].is_erased = -1;
228 bank->sectors[num_sectors].is_protected = 1;
229 str9xpec_info->sector_bits[num_sectors++] = i + 32;
232 return ERROR_OK;
235 /* flash bank str9x <base> <size> 0 0 <target#>
237 FLASH_BANK_COMMAND_HANDLER(str9xpec_flash_bank_command)
239 struct str9xpec_flash_controller *str9xpec_info;
240 struct arm *armv4_5 = NULL;
241 struct arm7_9_common *arm7_9 = NULL;
242 struct arm_jtag *jtag_info = NULL;
244 if (CMD_ARGC < 6)
246 LOG_WARNING("incomplete flash_bank str9x configuration");
247 return ERROR_FLASH_BANK_INVALID;
250 str9xpec_info = malloc(sizeof(struct str9xpec_flash_controller));
251 bank->driver_priv = str9xpec_info;
253 /* REVISIT verify that the jtag position of flash controller is
254 * right after *THIS* core, which must be a STR9xx core ...
256 armv4_5 = bank->target->arch_info;
257 arm7_9 = armv4_5->arch_info;
258 jtag_info = &arm7_9->jtag_info;
260 str9xpec_info->tap = bank->target->tap;
261 str9xpec_info->isc_enable = 0;
263 str9xpec_build_block_list(bank);
265 /* clear option byte register */
266 buf_set_u32(str9xpec_info->options, 0, 64, 0);
268 return ERROR_OK;
271 static int str9xpec_blank_check(struct flash_bank *bank, int first, int last)
273 struct scan_field field;
274 uint8_t status;
275 struct jtag_tap *tap;
276 int i;
277 uint8_t *buffer = NULL;
279 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
281 tap = str9xpec_info->tap;
283 if (!str9xpec_info->isc_enable) {
284 str9xpec_isc_enable(bank);
287 if (!str9xpec_info->isc_enable) {
288 return ERROR_FLASH_OPERATION_FAILED;
291 buffer = calloc(DIV_ROUND_UP(64, 8), 1);
293 LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first, last);
295 for (i = first; i <= last; i++) {
296 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
299 /* execute ISC_BLANK_CHECK command */
300 str9xpec_set_instr(tap, ISC_BLANK_CHECK, TAP_IRPAUSE);
302 field.num_bits = 64;
303 field.out_value = buffer;
304 field.in_value = NULL;
306 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
307 jtag_add_sleep(40000);
309 /* read blank check result */
310 field.num_bits = 64;
311 field.out_value = NULL;
312 field.in_value = buffer;
314 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
315 jtag_execute_queue();
317 status = str9xpec_isc_status(tap);
319 for (i = first; i <= last; i++)
321 if (buf_get_u32(buffer, str9xpec_info->sector_bits[i], 1))
322 bank->sectors[i].is_erased = 0;
323 else
324 bank->sectors[i].is_erased = 1;
327 free(buffer);
329 str9xpec_isc_disable(bank);
331 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
332 return ERROR_FLASH_OPERATION_FAILED;
333 return ERROR_OK;
336 static int str9xpec_protect_check(struct flash_bank *bank)
338 uint8_t status;
339 int i;
341 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
343 status = str9xpec_read_config(bank);
345 for (i = 0; i < bank->num_sectors; i++)
347 if (buf_get_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1))
348 bank->sectors[i].is_protected = 1;
349 else
350 bank->sectors[i].is_protected = 0;
353 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
354 return ERROR_FLASH_OPERATION_FAILED;
355 return ERROR_OK;
358 static int str9xpec_erase_area(struct flash_bank *bank, int first, int last)
360 struct scan_field field;
361 uint8_t status;
362 struct jtag_tap *tap;
363 int i;
364 uint8_t *buffer = NULL;
366 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
368 tap = str9xpec_info->tap;
370 if (!str9xpec_info->isc_enable) {
371 str9xpec_isc_enable(bank);
374 if (!str9xpec_info->isc_enable) {
375 return ISC_STATUS_ERROR;
378 buffer = calloc(DIV_ROUND_UP(64, 8), 1);
380 LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first, last);
382 /* last bank: 0xFF signals a full erase (unlock complete device) */
383 /* last bank: 0xFE signals a option byte erase */
384 if (last == 0xFF)
386 for (i = 0; i < 64; i++) {
387 buf_set_u32(buffer, i, 1, 1);
390 else if (last == 0xFE)
392 buf_set_u32(buffer, 49, 1, 1);
394 else
396 for (i = first; i <= last; i++) {
397 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
401 LOG_DEBUG("ISC_ERASE");
403 /* execute ISC_ERASE command */
404 str9xpec_set_instr(tap, ISC_ERASE, TAP_IRPAUSE);
406 field.num_bits = 64;
407 field.out_value = buffer;
408 field.in_value = NULL;
410 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
411 jtag_execute_queue();
413 jtag_add_sleep(10);
415 /* wait for erase completion */
416 while (!((status = str9xpec_isc_status(tap)) & ISC_STATUS_BUSY)) {
417 alive_sleep(1);
420 free(buffer);
422 str9xpec_isc_disable(bank);
424 return status;
427 static int str9xpec_erase(struct flash_bank *bank, int first, int last)
429 int status;
431 status = str9xpec_erase_area(bank, first, last);
433 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
434 return ERROR_FLASH_OPERATION_FAILED;
436 return ERROR_OK;
439 static int str9xpec_lock_device(struct flash_bank *bank)
441 struct scan_field field;
442 uint8_t status;
443 struct jtag_tap *tap;
444 struct str9xpec_flash_controller *str9xpec_info = NULL;
446 str9xpec_info = bank->driver_priv;
447 tap = str9xpec_info->tap;
449 if (!str9xpec_info->isc_enable) {
450 str9xpec_isc_enable(bank);
453 if (!str9xpec_info->isc_enable) {
454 return ISC_STATUS_ERROR;
457 /* set security address */
458 str9xpec_set_address(bank, 0x80);
460 /* execute ISC_PROGRAM command */
461 str9xpec_set_instr(tap, ISC_PROGRAM_SECURITY, TAP_IDLE);
463 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
465 do {
466 field.num_bits = 8;
467 field.out_value = NULL;
468 field.in_value = &status;
470 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
471 jtag_execute_queue();
473 } while (!(status & ISC_STATUS_BUSY));
475 str9xpec_isc_disable(bank);
477 return status;
480 static int str9xpec_unlock_device(struct flash_bank *bank)
482 uint8_t status;
484 status = str9xpec_erase_area(bank, 0, 255);
486 return status;
489 static int str9xpec_protect(struct flash_bank *bank, int set, int first, int last)
491 uint8_t status;
492 int i;
494 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
496 status = str9xpec_read_config(bank);
498 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
499 return ERROR_FLASH_OPERATION_FAILED;
501 LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first, last);
503 /* last bank: 0xFF signals a full device protect */
504 if (last == 0xFF)
506 if (set)
508 status = str9xpec_lock_device(bank);
510 else
512 /* perform full erase to unlock device */
513 status = str9xpec_unlock_device(bank);
516 else
518 for (i = first; i <= last; i++)
520 if (set)
521 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 1);
522 else
523 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 0);
526 status = str9xpec_write_options(bank);
529 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
530 return ERROR_FLASH_OPERATION_FAILED;
532 return ERROR_OK;
535 static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector)
537 struct jtag_tap *tap;
538 struct scan_field field;
539 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
541 tap = str9xpec_info->tap;
543 /* set flash controller address */
544 str9xpec_set_instr(tap, ISC_ADDRESS_SHIFT, TAP_IRPAUSE);
546 field.num_bits = 8;
547 field.out_value = &sector;
548 field.in_value = NULL;
550 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
552 return ERROR_OK;
555 static int str9xpec_write(struct flash_bank *bank, uint8_t *buffer,
556 uint32_t offset, uint32_t count)
558 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
559 uint32_t dwords_remaining = (count / 8);
560 uint32_t bytes_remaining = (count & 0x00000007);
561 uint32_t bytes_written = 0;
562 uint8_t status;
563 uint32_t check_address = offset;
564 struct jtag_tap *tap;
565 struct scan_field field;
566 uint8_t *scanbuf;
567 int i;
568 int first_sector = 0;
569 int last_sector = 0;
571 tap = str9xpec_info->tap;
573 if (!str9xpec_info->isc_enable) {
574 str9xpec_isc_enable(bank);
577 if (!str9xpec_info->isc_enable) {
578 return ERROR_FLASH_OPERATION_FAILED;
581 if (offset & 0x7)
583 LOG_WARNING("offset 0x%" PRIx32 " breaks required 8-byte alignment", offset);
584 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
587 for (i = 0; i < bank->num_sectors; i++)
589 uint32_t sec_start = bank->sectors[i].offset;
590 uint32_t sec_end = sec_start + bank->sectors[i].size;
592 /* check if destination falls within the current sector */
593 if ((check_address >= sec_start) && (check_address < sec_end))
595 /* check if destination ends in the current sector */
596 if (offset + count < sec_end)
597 check_address = offset + count;
598 else
599 check_address = sec_end;
602 if ((offset >= sec_start) && (offset < sec_end)) {
603 first_sector = i;
606 if ((offset + count >= sec_start) && (offset + count < sec_end)) {
607 last_sector = i;
611 if (check_address != offset + count)
612 return ERROR_FLASH_DST_OUT_OF_BANK;
614 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
616 scanbuf = calloc(DIV_ROUND_UP(64, 8), 1);
618 LOG_DEBUG("ISC_PROGRAM");
620 for (i = first_sector; i <= last_sector; i++)
622 str9xpec_set_address(bank, str9xpec_info->sector_bits[i]);
624 dwords_remaining = dwords_remaining < (bank->sectors[i].size/8)
625 ? dwords_remaining : (bank->sectors[i].size/8);
627 while (dwords_remaining > 0)
629 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
631 field.num_bits = 64;
632 field.out_value = (buffer + bytes_written);
633 field.in_value = NULL;
635 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
637 /* small delay before polling */
638 jtag_add_sleep(50);
640 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
642 do {
643 field.num_bits = 8;
644 field.out_value = NULL;
645 field.in_value = scanbuf;
647 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
648 jtag_execute_queue();
650 status = buf_get_u32(scanbuf, 0, 8);
652 } while (!(status & ISC_STATUS_BUSY));
654 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
655 return ERROR_FLASH_OPERATION_FAILED;
657 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
658 return ERROR_FLASH_OPERATION_FAILED; */
660 dwords_remaining--;
661 bytes_written += 8;
665 if (bytes_remaining)
667 uint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
668 i = 0;
670 while (bytes_remaining > 0)
672 last_dword[i++] = *(buffer + bytes_written);
673 bytes_remaining--;
674 bytes_written++;
677 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
679 field.num_bits = 64;
680 field.out_value = last_dword;
681 field.in_value = NULL;
683 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
685 /* small delay before polling */
686 jtag_add_sleep(50);
688 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
690 do {
691 field.num_bits = 8;
692 field.out_value = NULL;
693 field.in_value = scanbuf;
695 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
696 jtag_execute_queue();
698 status = buf_get_u32(scanbuf, 0, 8);
700 } while (!(status & ISC_STATUS_BUSY));
702 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
703 return ERROR_FLASH_OPERATION_FAILED;
705 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
706 return ERROR_FLASH_OPERATION_FAILED; */
709 free(scanbuf);
711 str9xpec_isc_disable(bank);
713 return ERROR_OK;
716 static int str9xpec_probe(struct flash_bank *bank)
718 return ERROR_OK;
721 COMMAND_HANDLER(str9xpec_handle_part_id_command)
723 struct scan_field field;
724 uint8_t *buffer = NULL;
725 struct jtag_tap *tap;
726 uint32_t idcode;
727 struct str9xpec_flash_controller *str9xpec_info = NULL;
729 if (CMD_ARGC < 1)
730 return ERROR_COMMAND_SYNTAX_ERROR;
732 struct flash_bank *bank;
733 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
734 if (ERROR_OK != retval)
735 return retval;
737 str9xpec_info = bank->driver_priv;
738 tap = str9xpec_info->tap;
740 buffer = calloc(DIV_ROUND_UP(32, 8), 1);
742 str9xpec_set_instr(tap, ISC_IDCODE, TAP_IRPAUSE);
744 field.num_bits = 32;
745 field.out_value = NULL;
746 field.in_value = buffer;
748 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
749 jtag_execute_queue();
751 idcode = buf_get_u32(buffer, 0, 32);
753 command_print(CMD_CTX, "str9xpec part id: 0x%8.8" PRIx32 "", idcode);
755 free(buffer);
757 return ERROR_OK;
760 static int str9xpec_erase_check(struct flash_bank *bank)
762 return str9xpec_blank_check(bank, 0, bank->num_sectors - 1);
765 static int get_str9xpec_info(struct flash_bank *bank, char *buf, int buf_size)
767 snprintf(buf, buf_size, "str9xpec flash driver info");
768 return ERROR_OK;
771 COMMAND_HANDLER(str9xpec_handle_flash_options_read_command)
773 uint8_t status;
774 struct str9xpec_flash_controller *str9xpec_info = NULL;
776 if (CMD_ARGC < 1)
778 command_print(CMD_CTX, "str9xpec options_read <bank>");
779 return ERROR_OK;
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;
787 str9xpec_info = bank->driver_priv;
789 status = str9xpec_read_config(bank);
791 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
792 return ERROR_FLASH_OPERATION_FAILED;
794 /* boot bank */
795 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1))
796 command_print(CMD_CTX, "CS Map: bank1");
797 else
798 command_print(CMD_CTX, "CS Map: bank0");
800 /* OTP lock */
801 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1))
802 command_print(CMD_CTX, "OTP Lock: OTP Locked");
803 else
804 command_print(CMD_CTX, "OTP Lock: OTP Unlocked");
806 /* LVD Threshold */
807 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1))
808 command_print(CMD_CTX, "LVD Threshold: 2.7v");
809 else
810 command_print(CMD_CTX, "LVD Threshold: 2.4v");
812 /* LVD reset warning */
813 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1))
814 command_print(CMD_CTX, "LVD Reset Warning: VDD or VDDQ Inputs");
815 else
816 command_print(CMD_CTX, "LVD Reset Warning: VDD Input Only");
818 /* LVD reset select */
819 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1))
820 command_print(CMD_CTX, "LVD Reset Selection: VDD or VDDQ Inputs");
821 else
822 command_print(CMD_CTX, "LVD Reset Selection: VDD Input Only");
824 return ERROR_OK;
827 static int str9xpec_write_options(struct flash_bank *bank)
829 struct scan_field field;
830 uint8_t status;
831 struct jtag_tap *tap;
832 struct str9xpec_flash_controller *str9xpec_info = NULL;
834 str9xpec_info = bank->driver_priv;
835 tap = str9xpec_info->tap;
837 /* erase config options first */
838 status = str9xpec_erase_area(bank, 0xFE, 0xFE);
840 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
841 return status;
843 if (!str9xpec_info->isc_enable) {
844 str9xpec_isc_enable(bank);
847 if (!str9xpec_info->isc_enable) {
848 return ISC_STATUS_ERROR;
851 /* according to data 64th bit has to be set */
852 buf_set_u32(str9xpec_info->options, 63, 1, 1);
854 /* set option byte address */
855 str9xpec_set_address(bank, 0x50);
857 /* execute ISC_PROGRAM command */
858 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
860 field.num_bits = 64;
861 field.out_value = str9xpec_info->options;
862 field.in_value = NULL;
864 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
866 /* small delay before polling */
867 jtag_add_sleep(50);
869 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
871 do {
872 field.num_bits = 8;
873 field.out_value = NULL;
874 field.in_value = &status;
876 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
877 jtag_execute_queue();
879 } while (!(status & ISC_STATUS_BUSY));
881 str9xpec_isc_disable(bank);
883 return status;
886 COMMAND_HANDLER(str9xpec_handle_flash_options_write_command)
888 uint8_t status;
890 if (CMD_ARGC < 1)
892 command_print(CMD_CTX, "str9xpec options_write <bank>");
893 return ERROR_OK;
896 struct flash_bank *bank;
897 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
898 if (ERROR_OK != retval)
899 return retval;
901 status = str9xpec_write_options(bank);
903 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
904 return ERROR_FLASH_OPERATION_FAILED;
906 command_print(CMD_CTX, "str9xpec write options complete.\n"
907 "INFO: a reset or power cycle is required "
908 "for the new settings to take effect.");
910 return ERROR_OK;
913 COMMAND_HANDLER(str9xpec_handle_flash_options_cmap_command)
915 struct str9xpec_flash_controller *str9xpec_info = NULL;
917 if (CMD_ARGC < 2)
919 command_print(CMD_CTX, "str9xpec options_cmap <bank> <bank0 | bank1>");
920 return ERROR_OK;
923 struct flash_bank *bank;
924 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
925 if (ERROR_OK != retval)
926 return retval;
928 str9xpec_info = bank->driver_priv;
930 if (strcmp(CMD_ARGV[1], "bank1") == 0)
932 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 1);
934 else
936 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0);
939 return ERROR_OK;
942 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdthd_command)
944 struct str9xpec_flash_controller *str9xpec_info = NULL;
946 if (CMD_ARGC < 2)
948 command_print(CMD_CTX, "str9xpec options_lvdthd <bank> <2.4v | 2.7v>");
949 return ERROR_OK;
952 struct flash_bank *bank;
953 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
954 if (ERROR_OK != retval)
955 return retval;
957 str9xpec_info = bank->driver_priv;
959 if (strcmp(CMD_ARGV[1], "2.7v") == 0)
961 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 1);
963 else
965 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0);
968 return ERROR_OK;
971 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdsel_command)
973 struct str9xpec_flash_controller *str9xpec_info = NULL;
975 if (CMD_ARGC < 2)
977 command_print(CMD_CTX, "str9xpec options_lvdsel <bank> <vdd | vdd_vddq>");
978 return ERROR_OK;
981 struct flash_bank *bank;
982 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
983 if (ERROR_OK != retval)
984 return retval;
986 str9xpec_info = bank->driver_priv;
988 if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0)
990 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 1);
992 else
994 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0);
997 return ERROR_OK;
1000 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdwarn_command)
1002 struct str9xpec_flash_controller *str9xpec_info = NULL;
1004 if (CMD_ARGC < 2)
1006 command_print(CMD_CTX, "str9xpec options_lvdwarn <bank> <vdd | vdd_vddq>");
1007 return ERROR_OK;
1010 struct flash_bank *bank;
1011 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1012 if (ERROR_OK != retval)
1013 return retval;
1015 str9xpec_info = bank->driver_priv;
1017 if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0)
1019 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 1);
1021 else
1023 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0);
1026 return ERROR_OK;
1029 COMMAND_HANDLER(str9xpec_handle_flash_lock_command)
1031 uint8_t status;
1033 if (CMD_ARGC < 1)
1035 command_print(CMD_CTX, "str9xpec lock <bank>");
1036 return ERROR_OK;
1039 struct flash_bank *bank;
1040 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1041 if (ERROR_OK != retval)
1042 return retval;
1044 status = str9xpec_lock_device(bank);
1046 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1047 return ERROR_FLASH_OPERATION_FAILED;
1049 return ERROR_OK;
1052 COMMAND_HANDLER(str9xpec_handle_flash_unlock_command)
1054 uint8_t status;
1056 if (CMD_ARGC < 1)
1058 command_print(CMD_CTX, "str9xpec unlock <bank>");
1059 return ERROR_OK;
1062 struct flash_bank *bank;
1063 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1064 if (ERROR_OK != retval)
1065 return retval;
1067 status = str9xpec_unlock_device(bank);
1069 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1070 return ERROR_FLASH_OPERATION_FAILED;
1072 command_print(CMD_CTX, "str9xpec unlocked.\n"
1073 "INFO: a reset or power cycle is required "
1074 "for the new settings to take effect.");
1076 return ERROR_OK;
1079 COMMAND_HANDLER(str9xpec_handle_flash_enable_turbo_command)
1081 struct jtag_tap *tap0;
1082 struct jtag_tap *tap1;
1083 struct jtag_tap *tap2;
1084 struct str9xpec_flash_controller *str9xpec_info = NULL;
1086 if (CMD_ARGC < 1)
1088 command_print(CMD_CTX, "str9xpec enable_turbo <bank>");
1089 return ERROR_OK;
1092 struct flash_bank *bank;
1093 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1094 if (ERROR_OK != retval)
1095 return retval;
1097 str9xpec_info = bank->driver_priv;
1099 tap0 = str9xpec_info->tap;
1101 /* remove arm core from chain - enter turbo mode */
1102 tap1 = tap0->next_tap;
1103 if (tap1 == NULL)
1105 /* things are *WRONG* */
1106 command_print(CMD_CTX,"**STR9FLASH** (tap1) invalid chain?");
1107 return ERROR_OK;
1109 tap2 = tap1->next_tap;
1110 if (tap2 == NULL)
1112 /* things are *WRONG* */
1113 command_print(CMD_CTX,"**STR9FLASH** (tap2) invalid chain?");
1114 return ERROR_OK;
1117 /* enable turbo mode - TURBO-PROG-ENABLE */
1118 str9xpec_set_instr(tap2, 0xD, TAP_IDLE);
1119 if ((retval = jtag_execute_queue()) != ERROR_OK)
1120 return retval;
1122 /* modify scan chain - str9 core has been removed */
1123 tap1->enabled = 0;
1125 return ERROR_OK;
1128 COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command)
1130 struct jtag_tap *tap;
1131 struct str9xpec_flash_controller *str9xpec_info = NULL;
1133 if (CMD_ARGC < 1)
1135 command_print(CMD_CTX, "str9xpec disable_turbo <bank>");
1136 return ERROR_OK;
1139 struct flash_bank *bank;
1140 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1141 if (ERROR_OK != retval)
1142 return retval;
1144 str9xpec_info = bank->driver_priv;
1145 tap = str9xpec_info->tap;
1147 if (tap == NULL)
1148 return ERROR_FAIL;
1150 /* exit turbo mode via RESET */
1151 str9xpec_set_instr(tap, ISC_NOOP, TAP_IDLE);
1152 jtag_add_tlr();
1153 jtag_execute_queue();
1155 /* restore previous scan chain */
1156 if (tap->next_tap) {
1157 tap->next_tap->enabled = 1;
1160 return ERROR_OK;
1163 static const struct command_registration str9xpec_config_command_handlers[] = {
1165 .name = "enable_turbo",
1166 .handler = str9xpec_handle_flash_enable_turbo_command,
1167 .mode = COMMAND_EXEC,
1168 .help = "enable str9xpec turbo mode",
1171 .name = "disable_turbo",
1172 .handler = str9xpec_handle_flash_disable_turbo_command,
1173 .mode = COMMAND_EXEC,
1174 .help = "disable str9xpec turbo mode",
1177 .name = "options_cmap",
1178 .handler = str9xpec_handle_flash_options_cmap_command,
1179 .mode = COMMAND_EXEC,
1180 .help = "configure str9xpec boot sector",
1183 .name = "options_lvdthd",
1184 .handler = str9xpec_handle_flash_options_lvdthd_command,
1185 .mode = COMMAND_EXEC,
1186 .help = "configure str9xpec lvd threshold",
1189 .name = "options_lvdsel",
1190 .handler = str9xpec_handle_flash_options_lvdsel_command,
1191 .mode = COMMAND_EXEC,
1192 .help = "configure str9xpec lvd selection",
1195 .name = "options_lvdwarn",
1196 .handler = str9xpec_handle_flash_options_lvdwarn_command,
1197 .mode = COMMAND_EXEC,
1198 .help = "configure str9xpec lvd warning",
1201 .name = "options_read",
1202 .handler = str9xpec_handle_flash_options_read_command,
1203 .mode = COMMAND_EXEC,
1204 .help = "read str9xpec options",
1207 .name = "options_write",
1208 .handler = str9xpec_handle_flash_options_write_command,
1209 .mode = COMMAND_EXEC,
1210 .help = "write str9xpec options",
1213 .name = "lock",
1214 .handler = str9xpec_handle_flash_lock_command,
1215 .mode = COMMAND_EXEC,
1216 .help = "lock str9xpec device",
1219 .name = "unlock",
1220 .handler = str9xpec_handle_flash_unlock_command,
1221 .mode = COMMAND_EXEC,
1222 .help = "unlock str9xpec device",
1225 .name = "part_id",
1226 .handler = str9xpec_handle_part_id_command,
1227 .mode = COMMAND_EXEC,
1228 .help = "print part id of str9xpec flash bank <num>",
1230 COMMAND_REGISTRATION_DONE
1233 static const struct command_registration str9xpec_command_handlers[] = {
1235 .name = "str9xpec",
1236 .mode = COMMAND_ANY,
1237 .help = "str9xpec flash command group",
1238 .chain = str9xpec_config_command_handlers,
1240 COMMAND_REGISTRATION_DONE
1243 struct flash_driver str9xpec_flash = {
1244 .name = "str9xpec",
1245 .commands = str9xpec_command_handlers,
1246 .flash_bank_command = str9xpec_flash_bank_command,
1247 .erase = str9xpec_erase,
1248 .protect = str9xpec_protect,
1249 .write = str9xpec_write,
1250 .read = default_flash_read,
1251 .probe = str9xpec_probe,
1252 .auto_probe = str9xpec_probe,
1253 .erase_check = str9xpec_erase_check,
1254 .protect_check = str9xpec_protect_check,
1255 .info = get_str9xpec_info,