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 get_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
= get_str9xpec_info
,