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 ***************************************************************************/
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)
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);
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);
60 static uint8_t str9xpec_isc_status(struct jtag_tap *tap)
62 struct scan_field field;
65 if (str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE) != ERROR_OK)
66 return ISC_STATUS_ERROR;
69 field.out_value = NULL;
70 field.in_value = &status;
73 jtag_add_dr_scan(tap, 1, &field, 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);
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);
168 static int str9xpec_build_block_list(struct flash_bank *bank)
170 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
174 int b0_sectors = 0, b1_sectors = 0;
176 int b1_size = 0x2000;
200 LOG_ERROR("BUG: unknown bank->size encountered");
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);
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;
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;
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);
271 static int str9xpec_blank_check(struct flash_bank *bank, int first, int last)
273 struct scan_field field;
275 struct jtag_tap *tap;
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);
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 */
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;
324 bank->sectors[i].is_erased = 1;
329 str9xpec_isc_disable(bank);
331 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
332 return ERROR_FLASH_OPERATION_FAILED;
336 static int str9xpec_protect_check(struct flash_bank *bank)
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;
350 bank->sectors[i].is_protected = 0;
353 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
354 return ERROR_FLASH_OPERATION_FAILED;
358 static int str9xpec_erase_area(struct flash_bank *bank, int first, int last)
360 struct scan_field field;
362 struct jtag_tap *tap;
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 */
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);
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);
407 field.out_value = buffer;
408 field.in_value = NULL;
410 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
411 jtag_execute_queue();
415 /* wait for erase completion */
416 while (!((status = str9xpec_isc_status(tap)) & ISC_STATUS_BUSY)) {
422 str9xpec_isc_disable(bank);
427 static int str9xpec_erase(struct flash_bank *bank, int first, int last)
431 status = str9xpec_erase_area(bank, first, last);
433 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
434 return ERROR_FLASH_OPERATION_FAILED;
439 static int str9xpec_lock_device(struct flash_bank *bank)
441 struct scan_field field;
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);
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);
480 static int str9xpec_unlock_device(struct flash_bank *bank)
484 status = str9xpec_erase_area(bank, 0, 255);
489 static int str9xpec_protect(struct flash_bank *bank, int set, int first, int last)
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 */
508 status = str9xpec_lock_device(bank);
512 /* perform full erase to unlock device */
513 status = str9xpec_unlock_device(bank);
518 for (i = first; i <= last; i++)
521 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 1);
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;
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);
547 field.out_value = §or;
548 field.in_value = NULL;
550 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
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;
563 uint32_t check_address = offset;
564 struct jtag_tap *tap;
565 struct scan_field field;
568 int first_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;
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;
599 check_address = sec_end;
602 if ((offset >= sec_start) && (offset < sec_end)) {
606 if ((offset + count >= sec_start) && (offset + count < sec_end)) {
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);
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 */
640 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
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; */
667 uint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
670 while (bytes_remaining > 0)
672 last_dword[i++] = *(buffer + bytes_written);
677 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
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 */
688 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
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; */
711 str9xpec_isc_disable(bank);
716 static int str9xpec_probe(struct flash_bank *bank)
721 COMMAND_HANDLER(str9xpec_handle_part_id_command)
723 struct scan_field field;
724 uint8_t *buffer = NULL;
725 struct jtag_tap *tap;
727 struct str9xpec_flash_controller *str9xpec_info = NULL;
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)
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);
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);
760 static int str9xpec_erase_check(struct flash_bank *bank)
762 return str9xpec_blank_check(bank, 0, bank->num_sectors - 1);
765 static int str9xpec_info(struct flash_bank *bank, char *buf, int buf_size)
767 snprintf(buf, buf_size, "str9xpec flash driver info");
771 COMMAND_HANDLER(str9xpec_handle_flash_options_read_command)
774 struct str9xpec_flash_controller *str9xpec_info = NULL;
778 command_print(CMD_CTX, "str9xpec options_read <bank>");
782 struct flash_bank *bank;
783 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
784 if (ERROR_OK != 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;
795 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1))
796 command_print(CMD_CTX, "CS Map: bank1");
798 command_print(CMD_CTX, "CS Map: bank0");
801 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1))
802 command_print(CMD_CTX, "OTP Lock: OTP Locked");
804 command_print(CMD_CTX, "OTP Lock: OTP Unlocked");
807 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1))
808 command_print(CMD_CTX, "LVD Threshold: 2.7v");
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");
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");
822 command_print(CMD_CTX, "LVD Reset Selection: VDD Input Only");
827 static int str9xpec_write_options(struct flash_bank *bank)
829 struct scan_field field;
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)
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);
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 */
869 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
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);
886 COMMAND_HANDLER(str9xpec_handle_flash_options_write_command)
892 command_print(CMD_CTX, "str9xpec options_write <bank>");
896 struct flash_bank *bank;
897 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
898 if (ERROR_OK != 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.");
913 COMMAND_HANDLER(str9xpec_handle_flash_options_cmap_command)
915 struct str9xpec_flash_controller *str9xpec_info = NULL;
919 command_print(CMD_CTX, "str9xpec options_cmap <bank> <bank0 | bank1>");
923 struct flash_bank *bank;
924 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
925 if (ERROR_OK != 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);
936 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0);
942 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdthd_command)
944 struct str9xpec_flash_controller *str9xpec_info = NULL;
948 command_print(CMD_CTX, "str9xpec options_lvdthd <bank> <2.4v | 2.7v>");
952 struct flash_bank *bank;
953 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
954 if (ERROR_OK != 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);
965 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0);
971 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdsel_command)
973 struct str9xpec_flash_controller *str9xpec_info = NULL;
977 command_print(CMD_CTX, "str9xpec options_lvdsel <bank> <vdd | vdd_vddq>");
981 struct flash_bank *bank;
982 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
983 if (ERROR_OK != 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);
994 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0);
1000 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdwarn_command)
1002 struct str9xpec_flash_controller *str9xpec_info = NULL;
1006 command_print(CMD_CTX, "str9xpec options_lvdwarn <bank> <vdd | vdd_vddq>");
1010 struct flash_bank *bank;
1011 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1012 if (ERROR_OK != 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);
1023 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0);
1029 COMMAND_HANDLER(str9xpec_handle_flash_lock_command)
1035 command_print(CMD_CTX, "str9xpec lock <bank>");
1039 struct flash_bank *bank;
1040 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1041 if (ERROR_OK != retval)
1044 status = str9xpec_lock_device(bank);
1046 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1047 return ERROR_FLASH_OPERATION_FAILED;
1052 COMMAND_HANDLER(str9xpec_handle_flash_unlock_command)
1058 command_print(CMD_CTX, "str9xpec unlock <bank>");
1062 struct flash_bank *bank;
1063 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1064 if (ERROR_OK != 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.");
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;
1088 command_print(CMD_CTX, "str9xpec enable_turbo <bank>");
1092 struct flash_bank *bank;
1093 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1094 if (ERROR_OK != 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;
1105 /* things are *WRONG* */
1106 command_print(CMD_CTX,"**STR9FLASH** (tap1) invalid chain?");
1109 tap2 = tap1->next_tap;
1112 /* things are *WRONG* */
1113 command_print(CMD_CTX,"**STR9FLASH** (tap2) invalid chain?");
1117 /* enable turbo mode - TURBO-PROG-ENABLE */
1118 str9xpec_set_instr(tap2, 0xD, TAP_IDLE);
1119 if ((retval = jtag_execute_queue()) != ERROR_OK)
1122 /* modify scan chain - str9 core has been removed */
1128 COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command)
1130 struct jtag_tap *tap;
1131 struct str9xpec_flash_controller *str9xpec_info = NULL;
1135 command_print(CMD_CTX, "str9xpec disable_turbo <bank>");
1139 struct flash_bank *bank;
1140 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1141 if (ERROR_OK != retval)
1144 str9xpec_info = bank->driver_priv;
1145 tap = str9xpec_info->tap;
1150 /* exit turbo mode via RESET */
1151 str9xpec_set_instr(tap, ISC_NOOP, TAP_IDLE);
1153 jtag_execute_queue();
1155 /* restore previous scan chain */
1156 if (tap->next_tap) {
1157 tap->next_tap->enabled = 1;
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",
1214 .handler = str9xpec_handle_flash_lock_command,
1215 .mode = COMMAND_EXEC,
1216 .help = "lock str9xpec device",
1220 .handler = str9xpec_handle_flash_unlock_command,
1221 .mode = COMMAND_EXEC,
1222 .help = "unlock str9xpec device",
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[] = {
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 = {
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 = str9xpec_info,