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_by_num
, 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_by_num
, 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_by_num
, 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_by_num
, 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_by_num
, 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_by_num
, 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_by_num
, 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_by_num
, 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_by_num
, 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_by_num
, 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_by_num
, 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 int str9xpec_register_commands(struct command_context
*cmd_ctx
)
1168 struct command
*str9xpec_cmd
= register_command(cmd_ctx
, NULL
, "str9xpec",
1169 NULL
, COMMAND_ANY
, "str9xpec flash specific commands");
1171 register_command(cmd_ctx
, str9xpec_cmd
, "enable_turbo",
1172 str9xpec_handle_flash_enable_turbo_command
,
1173 COMMAND_EXEC
, "enable str9xpec turbo mode");
1174 register_command(cmd_ctx
, str9xpec_cmd
, "disable_turbo",
1175 str9xpec_handle_flash_disable_turbo_command
,
1176 COMMAND_EXEC
, "disable str9xpec turbo mode");
1177 register_command(cmd_ctx
, str9xpec_cmd
, "options_cmap",
1178 str9xpec_handle_flash_options_cmap_command
,
1179 COMMAND_EXEC
, "configure str9xpec boot sector");
1180 register_command(cmd_ctx
, str9xpec_cmd
, "options_lvdthd",
1181 str9xpec_handle_flash_options_lvdthd_command
,
1182 COMMAND_EXEC
, "configure str9xpec lvd threshold");
1183 register_command(cmd_ctx
, str9xpec_cmd
, "options_lvdsel",
1184 str9xpec_handle_flash_options_lvdsel_command
,
1185 COMMAND_EXEC
, "configure str9xpec lvd selection");
1186 register_command(cmd_ctx
, str9xpec_cmd
, "options_lvdwarn",
1187 str9xpec_handle_flash_options_lvdwarn_command
,
1188 COMMAND_EXEC
, "configure str9xpec lvd warning");
1189 register_command(cmd_ctx
, str9xpec_cmd
, "options_read",
1190 str9xpec_handle_flash_options_read_command
,
1191 COMMAND_EXEC
, "read str9xpec options");
1192 register_command(cmd_ctx
, str9xpec_cmd
, "options_write",
1193 str9xpec_handle_flash_options_write_command
,
1194 COMMAND_EXEC
, "write str9xpec options");
1195 register_command(cmd_ctx
, str9xpec_cmd
, "lock",
1196 str9xpec_handle_flash_lock_command
,
1197 COMMAND_EXEC
, "lock str9xpec device");
1198 register_command(cmd_ctx
, str9xpec_cmd
, "unlock",
1199 str9xpec_handle_flash_unlock_command
,
1200 COMMAND_EXEC
, "unlock str9xpec device");
1201 register_command(cmd_ctx
, str9xpec_cmd
, "part_id",
1202 str9xpec_handle_part_id_command
,
1203 COMMAND_EXEC
, "print part id of str9xpec flash bank <num>");
1208 struct flash_driver str9xpec_flash
= {
1210 .register_commands
= &str9xpec_register_commands
,
1211 .flash_bank_command
= &str9xpec_flash_bank_command
,
1212 .erase
= &str9xpec_erase
,
1213 .protect
= &str9xpec_protect
,
1214 .write
= &str9xpec_write
,
1215 .probe
= &str9xpec_probe
,
1216 .auto_probe
= &str9xpec_probe
,
1217 .erase_check
= &str9xpec_erase_check
,
1218 .protect_check
= &str9xpec_protect_check
,
1219 .info
= &str9xpec_info
,