1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
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. *
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. *
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 ***************************************************************************/
28 #include "arm7_9_common.h"
31 static int str9xpec_erase_area(struct flash_bank *bank, int first, int last);
32 static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector);
33 static int str9xpec_write_options(struct flash_bank *bank);
35 int str9xpec_set_instr(struct jtag_tap *tap, uint32_t new_instr, tap_state_t end_state)
38 return ERROR_TARGET_INVALID;
41 if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr)
43 struct scan_field field;
46 field.num_bits = tap->ir_length;
47 field.out_value = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);
48 buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
49 field.in_value = NULL;
51 jtag_add_ir_scan(1, &field, end_state);
53 free(field.out_value);
59 static uint8_t str9xpec_isc_status(struct jtag_tap *tap)
61 struct scan_field field;
64 if (str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE) != ERROR_OK)
65 return ISC_STATUS_ERROR;
69 field.out_value = NULL;
70 field.in_value = &status;
73 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
76 LOG_DEBUG("status: 0x%2.2x", status);
78 if (status & ISC_STATUS_SECURITY)
79 LOG_INFO("Device Security Bit Set");
84 static int str9xpec_isc_enable(struct flash_bank *bank)
88 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
90 tap = str9xpec_info->tap;
92 if (str9xpec_info->isc_enable)
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");
111 static int str9xpec_isc_disable(struct flash_bank *bank)
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)
122 if (str9xpec_set_instr(tap, ISC_DISABLE, TAP_IDLE) != ERROR_OK)
123 return ERROR_TARGET_INVALID;
125 /* delay to handle aborts */
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");
140 static int str9xpec_read_config(struct flash_bank *bank)
142 struct scan_field field;
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);
157 field.out_value = NULL;
158 field.in_value = str9xpec_info->options;
161 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
162 jtag_execute_queue();
164 status = str9xpec_isc_status(tap);
169 static int str9xpec_build_block_list(struct flash_bank *bank)
171 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
175 int b0_sectors = 0, b1_sectors = 0;
177 int b1_size = 0x2000;
201 LOG_ERROR("BUG: unknown bank->size encountered");
205 num_sectors = b0_sectors + b1_sectors;
207 bank->num_sectors = num_sectors;
208 bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);
209 str9xpec_info->sector_bits = malloc(sizeof(uint32_t) * num_sectors);
213 for (i = 0; i < b0_sectors; i++)
215 bank->sectors[num_sectors].offset = offset;
216 bank->sectors[num_sectors].size = 0x10000;
217 offset += bank->sectors[i].size;
218 bank->sectors[num_sectors].is_erased = -1;
219 bank->sectors[num_sectors].is_protected = 1;
220 str9xpec_info->sector_bits[num_sectors++] = i;
223 for (i = 0; i < b1_sectors; i++)
225 bank->sectors[num_sectors].offset = offset;
226 bank->sectors[num_sectors].size = b1_size;
227 offset += bank->sectors[i].size;
228 bank->sectors[num_sectors].is_erased = -1;
229 bank->sectors[num_sectors].is_protected = 1;
230 str9xpec_info->sector_bits[num_sectors++] = i + 32;
236 /* flash bank str9x <base> <size> 0 0 <target#>
238 FLASH_BANK_COMMAND_HANDLER(str9xpec_flash_bank_command)
240 struct str9xpec_flash_controller *str9xpec_info;
241 struct arm *armv4_5 = NULL;
242 struct arm7_9_common *arm7_9 = NULL;
243 struct arm_jtag *jtag_info = NULL;
247 LOG_WARNING("incomplete flash_bank str9x configuration");
248 return ERROR_FLASH_BANK_INVALID;
251 str9xpec_info = malloc(sizeof(struct str9xpec_flash_controller));
252 bank->driver_priv = str9xpec_info;
254 /* REVISIT verify that the jtag position of flash controller is
255 * right after *THIS* core, which must be a STR9xx core ...
257 armv4_5 = bank->target->arch_info;
258 arm7_9 = armv4_5->arch_info;
259 jtag_info = &arm7_9->jtag_info;
261 str9xpec_info->tap = bank->target->tap;
262 str9xpec_info->isc_enable = 0;
264 str9xpec_build_block_list(bank);
266 /* clear option byte register */
267 buf_set_u32(str9xpec_info->options, 0, 64, 0);
272 static int str9xpec_blank_check(struct flash_bank *bank, int first, int last)
274 struct scan_field field;
276 struct jtag_tap *tap;
278 uint8_t *buffer = NULL;
280 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
282 tap = str9xpec_info->tap;
284 if (!str9xpec_info->isc_enable) {
285 str9xpec_isc_enable(bank);
288 if (!str9xpec_info->isc_enable) {
289 return ERROR_FLASH_OPERATION_FAILED;
292 buffer = calloc(DIV_ROUND_UP(64, 8), 1);
294 LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first, last);
296 for (i = first; i <= last; i++) {
297 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
300 /* execute ISC_BLANK_CHECK command */
301 str9xpec_set_instr(tap, ISC_BLANK_CHECK, TAP_IRPAUSE);
305 field.out_value = buffer;
306 field.in_value = NULL;
308 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
309 jtag_add_sleep(40000);
311 /* read blank check result */
314 field.out_value = NULL;
315 field.in_value = buffer;
317 jtag_add_dr_scan(1, &field, TAP_IRPAUSE);
318 jtag_execute_queue();
320 status = str9xpec_isc_status(tap);
322 for (i = first; i <= last; i++)
324 if (buf_get_u32(buffer, str9xpec_info->sector_bits[i], 1))
325 bank->sectors[i].is_erased = 0;
327 bank->sectors[i].is_erased = 1;
332 str9xpec_isc_disable(bank);
334 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
335 return ERROR_FLASH_OPERATION_FAILED;
339 static int str9xpec_protect_check(struct flash_bank *bank)
344 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
346 status = str9xpec_read_config(bank);
348 for (i = 0; i < bank->num_sectors; i++)
350 if (buf_get_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1))
351 bank->sectors[i].is_protected = 1;
353 bank->sectors[i].is_protected = 0;
356 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
357 return ERROR_FLASH_OPERATION_FAILED;
361 static int str9xpec_erase_area(struct flash_bank *bank, int first, int last)
363 struct scan_field field;
365 struct jtag_tap *tap;
367 uint8_t *buffer = NULL;
369 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
371 tap = str9xpec_info->tap;
373 if (!str9xpec_info->isc_enable) {
374 str9xpec_isc_enable(bank);
377 if (!str9xpec_info->isc_enable) {
378 return ISC_STATUS_ERROR;
381 buffer = calloc(DIV_ROUND_UP(64, 8), 1);
383 LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first, last);
385 /* last bank: 0xFF signals a full erase (unlock complete device) */
386 /* last bank: 0xFE signals a option byte erase */
389 for (i = 0; i < 64; i++) {
390 buf_set_u32(buffer, i, 1, 1);
393 else if (last == 0xFE)
395 buf_set_u32(buffer, 49, 1, 1);
399 for (i = first; i <= last; i++) {
400 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
404 LOG_DEBUG("ISC_ERASE");
406 /* execute ISC_ERASE command */
407 str9xpec_set_instr(tap, ISC_ERASE, TAP_IRPAUSE);
411 field.out_value = buffer;
412 field.in_value = NULL;
414 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
415 jtag_execute_queue();
419 /* wait for erase completion */
420 while (!((status = str9xpec_isc_status(tap)) & ISC_STATUS_BUSY)) {
426 str9xpec_isc_disable(bank);
431 static int str9xpec_erase(struct flash_bank *bank, int first, int last)
435 status = str9xpec_erase_area(bank, first, last);
437 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
438 return ERROR_FLASH_OPERATION_FAILED;
443 static int str9xpec_lock_device(struct flash_bank *bank)
445 struct scan_field field;
447 struct jtag_tap *tap;
448 struct str9xpec_flash_controller *str9xpec_info = NULL;
450 str9xpec_info = bank->driver_priv;
451 tap = str9xpec_info->tap;
453 if (!str9xpec_info->isc_enable) {
454 str9xpec_isc_enable(bank);
457 if (!str9xpec_info->isc_enable) {
458 return ISC_STATUS_ERROR;
461 /* set security address */
462 str9xpec_set_address(bank, 0x80);
464 /* execute ISC_PROGRAM command */
465 str9xpec_set_instr(tap, ISC_PROGRAM_SECURITY, TAP_IDLE);
467 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
472 field.out_value = NULL;
473 field.in_value = &status;
475 jtag_add_dr_scan(1, &field, jtag_get_end_state());
476 jtag_execute_queue();
478 } while (!(status & ISC_STATUS_BUSY));
480 str9xpec_isc_disable(bank);
485 static int str9xpec_unlock_device(struct flash_bank *bank)
489 status = str9xpec_erase_area(bank, 0, 255);
494 static int str9xpec_protect(struct flash_bank *bank, int set, int first, int last)
499 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
501 status = str9xpec_read_config(bank);
503 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
504 return ERROR_FLASH_OPERATION_FAILED;
506 LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first, last);
508 /* last bank: 0xFF signals a full device protect */
513 status = str9xpec_lock_device(bank);
517 /* perform full erase to unlock device */
518 status = str9xpec_unlock_device(bank);
523 for (i = first; i <= last; i++)
526 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 1);
528 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 0);
531 status = str9xpec_write_options(bank);
534 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
535 return ERROR_FLASH_OPERATION_FAILED;
540 static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector)
542 struct jtag_tap *tap;
543 struct scan_field field;
544 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
546 tap = str9xpec_info->tap;
548 /* set flash controller address */
549 str9xpec_set_instr(tap, ISC_ADDRESS_SHIFT, TAP_IRPAUSE);
553 field.out_value = §or;
554 field.in_value = NULL;
556 jtag_add_dr_scan(1, &field, jtag_get_end_state());
561 static int str9xpec_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
563 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
564 uint32_t dwords_remaining = (count / 8);
565 uint32_t bytes_remaining = (count & 0x00000007);
566 uint32_t bytes_written = 0;
568 uint32_t check_address = offset;
569 struct jtag_tap *tap;
570 struct scan_field field;
573 int first_sector = 0;
576 tap = str9xpec_info->tap;
578 if (!str9xpec_info->isc_enable) {
579 str9xpec_isc_enable(bank);
582 if (!str9xpec_info->isc_enable) {
583 return ERROR_FLASH_OPERATION_FAILED;
588 LOG_WARNING("offset 0x%" PRIx32 " breaks required 8-byte alignment", offset);
589 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
592 for (i = 0; i < bank->num_sectors; i++)
594 uint32_t sec_start = bank->sectors[i].offset;
595 uint32_t sec_end = sec_start + bank->sectors[i].size;
597 /* check if destination falls within the current sector */
598 if ((check_address >= sec_start) && (check_address < sec_end))
600 /* check if destination ends in the current sector */
601 if (offset + count < sec_end)
602 check_address = offset + count;
604 check_address = sec_end;
607 if ((offset >= sec_start) && (offset < sec_end)) {
611 if ((offset + count >= sec_start) && (offset + count < sec_end)) {
616 if (check_address != offset + count)
617 return ERROR_FLASH_DST_OUT_OF_BANK;
619 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
621 scanbuf = calloc(DIV_ROUND_UP(64, 8), 1);
623 LOG_DEBUG("ISC_PROGRAM");
625 for (i = first_sector; i <= last_sector; i++)
627 str9xpec_set_address(bank, str9xpec_info->sector_bits[i]);
629 dwords_remaining = dwords_remaining < (bank->sectors[i].size/8) ? dwords_remaining : (bank->sectors[i].size/8);
631 while (dwords_remaining > 0)
633 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
637 field.out_value = (buffer + bytes_written);
638 field.in_value = NULL;
640 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
642 /* small delay before polling */
645 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
650 field.out_value = NULL;
651 field.in_value = scanbuf;
653 jtag_add_dr_scan(1, &field, jtag_get_end_state());
654 jtag_execute_queue();
656 status = buf_get_u32(scanbuf, 0, 8);
658 } while (!(status & ISC_STATUS_BUSY));
660 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
661 return ERROR_FLASH_OPERATION_FAILED;
663 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
664 return ERROR_FLASH_OPERATION_FAILED; */
673 uint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
676 while (bytes_remaining > 0)
678 last_dword[i++] = *(buffer + bytes_written);
683 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
687 field.out_value = last_dword;
688 field.in_value = NULL;
690 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
692 /* small delay before polling */
695 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
700 field.out_value = NULL;
701 field.in_value = scanbuf;
703 jtag_add_dr_scan(1, &field, jtag_get_end_state());
704 jtag_execute_queue();
706 status = buf_get_u32(scanbuf, 0, 8);
708 } while (!(status & ISC_STATUS_BUSY));
710 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
711 return ERROR_FLASH_OPERATION_FAILED;
713 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
714 return ERROR_FLASH_OPERATION_FAILED; */
719 str9xpec_isc_disable(bank);
724 static int str9xpec_probe(struct flash_bank *bank)
729 COMMAND_HANDLER(str9xpec_handle_part_id_command)
731 struct scan_field field;
732 uint8_t *buffer = NULL;
733 struct jtag_tap *tap;
735 struct str9xpec_flash_controller *str9xpec_info = NULL;
738 return ERROR_COMMAND_SYNTAX_ERROR;
740 struct flash_bank *bank;
741 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
742 if (ERROR_OK != retval)
745 str9xpec_info = bank->driver_priv;
746 tap = str9xpec_info->tap;
748 buffer = calloc(DIV_ROUND_UP(32, 8), 1);
750 str9xpec_set_instr(tap, ISC_IDCODE, TAP_IRPAUSE);
754 field.out_value = NULL;
755 field.in_value = buffer;
757 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
758 jtag_execute_queue();
760 idcode = buf_get_u32(buffer, 0, 32);
762 command_print(CMD_CTX, "str9xpec part id: 0x%8.8" PRIx32 "", idcode);
769 static int str9xpec_erase_check(struct flash_bank *bank)
771 return str9xpec_blank_check(bank, 0, bank->num_sectors - 1);
774 static int str9xpec_info(struct flash_bank *bank, char *buf, int buf_size)
776 snprintf(buf, buf_size, "str9xpec flash driver info");
780 COMMAND_HANDLER(str9xpec_handle_flash_options_read_command)
783 struct str9xpec_flash_controller *str9xpec_info = NULL;
787 command_print(CMD_CTX, "str9xpec options_read <bank>");
791 struct flash_bank *bank;
792 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
793 if (ERROR_OK != retval)
796 str9xpec_info = bank->driver_priv;
798 status = str9xpec_read_config(bank);
800 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
801 return ERROR_FLASH_OPERATION_FAILED;
804 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1))
805 command_print(CMD_CTX, "CS Map: bank1");
807 command_print(CMD_CTX, "CS Map: bank0");
810 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1))
811 command_print(CMD_CTX, "OTP Lock: OTP Locked");
813 command_print(CMD_CTX, "OTP Lock: OTP Unlocked");
816 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1))
817 command_print(CMD_CTX, "LVD Threshold: 2.7v");
819 command_print(CMD_CTX, "LVD Threshold: 2.4v");
821 /* LVD reset warning */
822 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1))
823 command_print(CMD_CTX, "LVD Reset Warning: VDD or VDDQ Inputs");
825 command_print(CMD_CTX, "LVD Reset Warning: VDD Input Only");
827 /* LVD reset select */
828 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1))
829 command_print(CMD_CTX, "LVD Reset Selection: VDD or VDDQ Inputs");
831 command_print(CMD_CTX, "LVD Reset Selection: VDD Input Only");
836 static int str9xpec_write_options(struct flash_bank *bank)
838 struct scan_field field;
840 struct jtag_tap *tap;
841 struct str9xpec_flash_controller *str9xpec_info = NULL;
843 str9xpec_info = bank->driver_priv;
844 tap = str9xpec_info->tap;
846 /* erase config options first */
847 status = str9xpec_erase_area(bank, 0xFE, 0xFE);
849 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
852 if (!str9xpec_info->isc_enable) {
853 str9xpec_isc_enable(bank);
856 if (!str9xpec_info->isc_enable) {
857 return ISC_STATUS_ERROR;
860 /* according to data 64th bit has to be set */
861 buf_set_u32(str9xpec_info->options, 63, 1, 1);
863 /* set option byte address */
864 str9xpec_set_address(bank, 0x50);
866 /* execute ISC_PROGRAM command */
867 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
871 field.out_value = str9xpec_info->options;
872 field.in_value = NULL;
874 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
876 /* small delay before polling */
879 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
884 field.out_value = NULL;
885 field.in_value = &status;
887 jtag_add_dr_scan(1, &field, jtag_get_end_state());
888 jtag_execute_queue();
890 } while (!(status & ISC_STATUS_BUSY));
892 str9xpec_isc_disable(bank);
897 COMMAND_HANDLER(str9xpec_handle_flash_options_write_command)
903 command_print(CMD_CTX, "str9xpec options_write <bank>");
907 struct flash_bank *bank;
908 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
909 if (ERROR_OK != retval)
912 status = str9xpec_write_options(bank);
914 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
915 return ERROR_FLASH_OPERATION_FAILED;
920 COMMAND_HANDLER(str9xpec_handle_flash_options_cmap_command)
922 struct str9xpec_flash_controller *str9xpec_info = NULL;
926 command_print(CMD_CTX, "str9xpec options_cmap <bank> <bank0 | bank1>");
930 struct flash_bank *bank;
931 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
932 if (ERROR_OK != retval)
935 str9xpec_info = bank->driver_priv;
937 if (strcmp(CMD_ARGV[1], "bank1") == 0)
939 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 1);
943 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0);
949 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdthd_command)
951 struct str9xpec_flash_controller *str9xpec_info = NULL;
955 command_print(CMD_CTX, "str9xpec options_lvdthd <bank> <2.4v | 2.7v>");
959 struct flash_bank *bank;
960 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
961 if (ERROR_OK != retval)
964 str9xpec_info = bank->driver_priv;
966 if (strcmp(CMD_ARGV[1], "2.7v") == 0)
968 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 1);
972 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0);
978 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdsel_command)
980 struct str9xpec_flash_controller *str9xpec_info = NULL;
984 command_print(CMD_CTX, "str9xpec options_lvdsel <bank> <vdd | vdd_vddq>");
988 struct flash_bank *bank;
989 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
990 if (ERROR_OK != retval)
993 str9xpec_info = bank->driver_priv;
995 if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0)
997 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 1);
1001 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0);
1007 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdwarn_command)
1009 struct str9xpec_flash_controller *str9xpec_info = NULL;
1013 command_print(CMD_CTX, "str9xpec options_lvdwarn <bank> <vdd | vdd_vddq>");
1017 struct flash_bank *bank;
1018 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1019 if (ERROR_OK != retval)
1022 str9xpec_info = bank->driver_priv;
1024 if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0)
1026 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 1);
1030 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0);
1036 COMMAND_HANDLER(str9xpec_handle_flash_lock_command)
1042 command_print(CMD_CTX, "str9xpec lock <bank>");
1046 struct flash_bank *bank;
1047 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1048 if (ERROR_OK != retval)
1051 status = str9xpec_lock_device(bank);
1053 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1054 return ERROR_FLASH_OPERATION_FAILED;
1059 COMMAND_HANDLER(str9xpec_handle_flash_unlock_command)
1065 command_print(CMD_CTX, "str9xpec unlock <bank>");
1069 struct flash_bank *bank;
1070 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1071 if (ERROR_OK != retval)
1074 status = str9xpec_unlock_device(bank);
1076 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1077 return ERROR_FLASH_OPERATION_FAILED;
1082 COMMAND_HANDLER(str9xpec_handle_flash_enable_turbo_command)
1084 struct jtag_tap *tap0;
1085 struct jtag_tap *tap1;
1086 struct jtag_tap *tap2;
1087 struct str9xpec_flash_controller *str9xpec_info = NULL;
1091 command_print(CMD_CTX, "str9xpec enable_turbo <bank>");
1095 struct flash_bank *bank;
1096 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1097 if (ERROR_OK != retval)
1100 str9xpec_info = bank->driver_priv;
1102 tap0 = str9xpec_info->tap;
1104 /* remove arm core from chain - enter turbo mode */
1105 tap1 = tap0->next_tap;
1108 /* things are *WRONG* */
1109 command_print(CMD_CTX,"**STR9FLASH** (tap1) invalid chain?");
1112 tap2 = tap1->next_tap;
1115 /* things are *WRONG* */
1116 command_print(CMD_CTX,"**STR9FLASH** (tap2) invalid chain?");
1120 /* enable turbo mode - TURBO-PROG-ENABLE */
1121 str9xpec_set_instr(tap2, 0xD, TAP_IDLE);
1122 if ((retval = jtag_execute_queue()) != ERROR_OK)
1125 /* modify scan chain - str9 core has been removed */
1131 COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command)
1133 struct jtag_tap *tap;
1134 struct str9xpec_flash_controller *str9xpec_info = NULL;
1138 command_print(CMD_CTX, "str9xpec disable_turbo <bank>");
1142 struct flash_bank *bank;
1143 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1144 if (ERROR_OK != retval)
1147 str9xpec_info = bank->driver_priv;
1148 tap = str9xpec_info->tap;
1153 /* exit turbo mode via RESET */
1154 str9xpec_set_instr(tap, ISC_NOOP, TAP_IDLE);
1156 jtag_execute_queue();
1158 /* restore previous scan chain */
1159 if (tap->next_tap) {
1160 tap->next_tap->enabled = 1;
1166 static const struct command_registration str9xpec_config_command_handlers[] = {
1168 .name = "enable_turbo",
1169 .handler = str9xpec_handle_flash_enable_turbo_command,
1170 .mode = COMMAND_EXEC,
1171 .help = "enable str9xpec turbo mode",
1174 .name = "disable_turbo",
1175 .handler = str9xpec_handle_flash_disable_turbo_command,
1176 .mode = COMMAND_EXEC,
1177 .help = "disable str9xpec turbo mode",
1180 .name = "options_cmap",
1181 .handler = str9xpec_handle_flash_options_cmap_command,
1182 .mode = COMMAND_EXEC,
1183 .help = "configure str9xpec boot sector",
1186 .name = "options_lvdthd",
1187 .handler = str9xpec_handle_flash_options_lvdthd_command,
1188 .mode = COMMAND_EXEC,
1189 .help = "configure str9xpec lvd threshold",
1192 .name = "options_lvdsel",
1193 .handler = str9xpec_handle_flash_options_lvdsel_command,
1194 .mode = COMMAND_EXEC,
1195 .help = "configure str9xpec lvd selection",
1198 .name = "options_lvdwarn",
1199 .handler = str9xpec_handle_flash_options_lvdwarn_command,
1200 .mode = COMMAND_EXEC,
1201 .help = "configure str9xpec lvd warning",
1204 .name = "options_read",
1205 .handler = str9xpec_handle_flash_options_read_command,
1206 .mode = COMMAND_EXEC,
1207 .help = "read str9xpec options",
1210 .name = "options_write",
1211 .handler = str9xpec_handle_flash_options_write_command,
1212 .mode = COMMAND_EXEC,
1213 .help = "write str9xpec options",
1217 .handler = str9xpec_handle_flash_lock_command,
1218 .mode = COMMAND_EXEC,
1219 .help = "lock str9xpec device",
1223 .handler = str9xpec_handle_flash_unlock_command,
1224 .mode = COMMAND_EXEC,
1225 .help = "unlock str9xpec device",
1229 .handler = str9xpec_handle_part_id_command,
1230 .mode = COMMAND_EXEC,
1231 .help = "print part id of str9xpec flash bank <num>",
1233 COMMAND_REGISTRATION_DONE
1235 static const struct command_registration str9xpec_command_handlers[] = {
1238 .mode = COMMAND_ANY,
1239 .help = "str9xpec flash command group",
1240 .chain = str9xpec_config_command_handlers,
1242 COMMAND_REGISTRATION_DONE
1245 struct flash_driver str9xpec_flash = {
1247 .commands = str9xpec_command_handlers,
1248 .flash_bank_command = &str9xpec_flash_bank_command,
1249 .erase = &str9xpec_erase,
1250 .protect = &str9xpec_protect,
1251 .write = &str9xpec_write,
1252 .probe = &str9xpec_probe,
1253 .auto_probe = &str9xpec_probe,
1254 .erase_check = &str9xpec_erase_check,
1255 .protect_check = &str9xpec_protect_check,
1256 .info = &str9xpec_info,