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 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
;
47 field
.num_bits
= tap
->ir_length
;
48 field
.out_value
= calloc(DIV_ROUND_UP(field
.num_bits
, 8), 1);
49 buf_set_u32(field
.out_value
, 0, field
.num_bits
, new_instr
);
50 field
.in_value
= NULL
;
52 jtag_add_ir_scan(1, &field
, end_state
);
54 free(field
.out_value
);
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
;
70 field
.out_value
= NULL
;
71 field
.in_value
= &status
;
74 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
77 LOG_DEBUG("status: 0x%2.2x", status
);
79 if (status
& ISC_STATUS_SECURITY
)
80 LOG_INFO("Device Security Bit Set");
85 static int str9xpec_isc_enable(struct flash_bank
*bank
)
89 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
91 tap
= str9xpec_info
->tap
;
93 if (str9xpec_info
->isc_enable
)
97 if (str9xpec_set_instr(tap
, ISC_ENABLE
, TAP_IDLE
) != ERROR_OK
)
98 return ERROR_TARGET_INVALID
;
100 /* check ISC status */
101 status
= str9xpec_isc_status(tap
);
102 if (status
& ISC_STATUS_MODE
)
104 /* we have entered isc mode */
105 str9xpec_info
->isc_enable
= 1;
106 LOG_DEBUG("ISC_MODE Enabled");
112 static int str9xpec_isc_disable(struct flash_bank
*bank
)
115 struct jtag_tap
*tap
;
116 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
118 tap
= str9xpec_info
->tap
;
120 if (!str9xpec_info
->isc_enable
)
123 if (str9xpec_set_instr(tap
, ISC_DISABLE
, TAP_IDLE
) != ERROR_OK
)
124 return ERROR_TARGET_INVALID
;
126 /* delay to handle aborts */
129 /* check ISC status */
130 status
= str9xpec_isc_status(tap
);
131 if (!(status
& ISC_STATUS_MODE
))
133 /* we have left isc mode */
134 str9xpec_info
->isc_enable
= 0;
135 LOG_DEBUG("ISC_MODE Disabled");
141 static int str9xpec_read_config(struct flash_bank
*bank
)
143 struct scan_field field
;
145 struct jtag_tap
*tap
;
147 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
149 tap
= str9xpec_info
->tap
;
151 LOG_DEBUG("ISC_CONFIGURATION");
153 /* execute ISC_CONFIGURATION command */
154 str9xpec_set_instr(tap
, ISC_CONFIGURATION
, TAP_IRPAUSE
);
158 field
.out_value
= NULL
;
159 field
.in_value
= str9xpec_info
->options
;
162 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
163 jtag_execute_queue();
165 status
= str9xpec_isc_status(tap
);
170 static int str9xpec_build_block_list(struct flash_bank
*bank
)
172 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
176 int b0_sectors
= 0, b1_sectors
= 0;
178 int b1_size
= 0x2000;
202 LOG_ERROR("BUG: unknown bank->size encountered");
206 num_sectors
= b0_sectors
+ b1_sectors
;
208 bank
->num_sectors
= num_sectors
;
209 bank
->sectors
= malloc(sizeof(struct flash_sector
) * num_sectors
);
210 str9xpec_info
->sector_bits
= malloc(sizeof(uint32_t) * num_sectors
);
214 for (i
= 0; i
< b0_sectors
; i
++)
216 bank
->sectors
[num_sectors
].offset
= offset
;
217 bank
->sectors
[num_sectors
].size
= 0x10000;
218 offset
+= bank
->sectors
[i
].size
;
219 bank
->sectors
[num_sectors
].is_erased
= -1;
220 bank
->sectors
[num_sectors
].is_protected
= 1;
221 str9xpec_info
->sector_bits
[num_sectors
++] = i
;
224 for (i
= 0; i
< b1_sectors
; i
++)
226 bank
->sectors
[num_sectors
].offset
= offset
;
227 bank
->sectors
[num_sectors
].size
= b1_size
;
228 offset
+= bank
->sectors
[i
].size
;
229 bank
->sectors
[num_sectors
].is_erased
= -1;
230 bank
->sectors
[num_sectors
].is_protected
= 1;
231 str9xpec_info
->sector_bits
[num_sectors
++] = i
+ 32;
237 /* flash bank str9x <base> <size> 0 0 <target#>
239 FLASH_BANK_COMMAND_HANDLER(str9xpec_flash_bank_command
)
241 struct str9xpec_flash_controller
*str9xpec_info
;
242 struct arm
*armv4_5
= NULL
;
243 struct arm7_9_common
*arm7_9
= NULL
;
244 struct arm_jtag
*jtag_info
= NULL
;
248 LOG_WARNING("incomplete flash_bank str9x configuration");
249 return ERROR_FLASH_BANK_INVALID
;
252 str9xpec_info
= malloc(sizeof(struct str9xpec_flash_controller
));
253 bank
->driver_priv
= str9xpec_info
;
255 /* REVISIT verify that the jtag position of flash controller is
256 * right after *THIS* core, which must be a STR9xx core ...
258 armv4_5
= bank
->target
->arch_info
;
259 arm7_9
= armv4_5
->arch_info
;
260 jtag_info
= &arm7_9
->jtag_info
;
262 str9xpec_info
->tap
= bank
->target
->tap
;
263 str9xpec_info
->isc_enable
= 0;
265 str9xpec_build_block_list(bank
);
267 /* clear option byte register */
268 buf_set_u32(str9xpec_info
->options
, 0, 64, 0);
273 static int str9xpec_blank_check(struct flash_bank
*bank
, int first
, int last
)
275 struct scan_field field
;
277 struct jtag_tap
*tap
;
279 uint8_t *buffer
= NULL
;
281 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
283 tap
= str9xpec_info
->tap
;
285 if (!str9xpec_info
->isc_enable
) {
286 str9xpec_isc_enable(bank
);
289 if (!str9xpec_info
->isc_enable
) {
290 return ERROR_FLASH_OPERATION_FAILED
;
293 buffer
= calloc(DIV_ROUND_UP(64, 8), 1);
295 LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first
, last
);
297 for (i
= first
; i
<= last
; i
++) {
298 buf_set_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1, 1);
301 /* execute ISC_BLANK_CHECK command */
302 str9xpec_set_instr(tap
, ISC_BLANK_CHECK
, TAP_IRPAUSE
);
306 field
.out_value
= buffer
;
307 field
.in_value
= NULL
;
309 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
310 jtag_add_sleep(40000);
312 /* read blank check result */
315 field
.out_value
= NULL
;
316 field
.in_value
= buffer
;
318 jtag_add_dr_scan(1, &field
, TAP_IRPAUSE
);
319 jtag_execute_queue();
321 status
= str9xpec_isc_status(tap
);
323 for (i
= first
; i
<= last
; i
++)
325 if (buf_get_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1))
326 bank
->sectors
[i
].is_erased
= 0;
328 bank
->sectors
[i
].is_erased
= 1;
333 str9xpec_isc_disable(bank
);
335 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
336 return ERROR_FLASH_OPERATION_FAILED
;
340 static int str9xpec_protect_check(struct flash_bank
*bank
)
345 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
347 status
= str9xpec_read_config(bank
);
349 for (i
= 0; i
< bank
->num_sectors
; i
++)
351 if (buf_get_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1))
352 bank
->sectors
[i
].is_protected
= 1;
354 bank
->sectors
[i
].is_protected
= 0;
357 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
358 return ERROR_FLASH_OPERATION_FAILED
;
362 static int str9xpec_erase_area(struct flash_bank
*bank
, int first
, int last
)
364 struct scan_field field
;
366 struct jtag_tap
*tap
;
368 uint8_t *buffer
= NULL
;
370 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
372 tap
= str9xpec_info
->tap
;
374 if (!str9xpec_info
->isc_enable
) {
375 str9xpec_isc_enable(bank
);
378 if (!str9xpec_info
->isc_enable
) {
379 return ISC_STATUS_ERROR
;
382 buffer
= calloc(DIV_ROUND_UP(64, 8), 1);
384 LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first
, last
);
386 /* last bank: 0xFF signals a full erase (unlock complete device) */
387 /* last bank: 0xFE signals a option byte erase */
390 for (i
= 0; i
< 64; i
++) {
391 buf_set_u32(buffer
, i
, 1, 1);
394 else if (last
== 0xFE)
396 buf_set_u32(buffer
, 49, 1, 1);
400 for (i
= first
; i
<= last
; i
++) {
401 buf_set_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1, 1);
405 LOG_DEBUG("ISC_ERASE");
407 /* execute ISC_ERASE command */
408 str9xpec_set_instr(tap
, ISC_ERASE
, TAP_IRPAUSE
);
412 field
.out_value
= buffer
;
413 field
.in_value
= NULL
;
415 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
416 jtag_execute_queue();
420 /* wait for erase completion */
421 while (!((status
= str9xpec_isc_status(tap
)) & ISC_STATUS_BUSY
)) {
427 str9xpec_isc_disable(bank
);
432 static int str9xpec_erase(struct flash_bank
*bank
, int first
, int last
)
436 status
= str9xpec_erase_area(bank
, first
, last
);
438 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
439 return ERROR_FLASH_OPERATION_FAILED
;
444 static int str9xpec_lock_device(struct flash_bank
*bank
)
446 struct scan_field field
;
448 struct jtag_tap
*tap
;
449 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
451 str9xpec_info
= bank
->driver_priv
;
452 tap
= str9xpec_info
->tap
;
454 if (!str9xpec_info
->isc_enable
) {
455 str9xpec_isc_enable(bank
);
458 if (!str9xpec_info
->isc_enable
) {
459 return ISC_STATUS_ERROR
;
462 /* set security address */
463 str9xpec_set_address(bank
, 0x80);
465 /* execute ISC_PROGRAM command */
466 str9xpec_set_instr(tap
, ISC_PROGRAM_SECURITY
, TAP_IDLE
);
468 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
473 field
.out_value
= NULL
;
474 field
.in_value
= &status
;
476 jtag_add_dr_scan(1, &field
, jtag_get_end_state());
477 jtag_execute_queue();
479 } while (!(status
& ISC_STATUS_BUSY
));
481 str9xpec_isc_disable(bank
);
486 static int str9xpec_unlock_device(struct flash_bank
*bank
)
490 status
= str9xpec_erase_area(bank
, 0, 255);
495 static int str9xpec_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
500 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
502 status
= str9xpec_read_config(bank
);
504 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
505 return ERROR_FLASH_OPERATION_FAILED
;
507 LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first
, last
);
509 /* last bank: 0xFF signals a full device protect */
514 status
= str9xpec_lock_device(bank
);
518 /* perform full erase to unlock device */
519 status
= str9xpec_unlock_device(bank
);
524 for (i
= first
; i
<= last
; i
++)
527 buf_set_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1, 1);
529 buf_set_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1, 0);
532 status
= str9xpec_write_options(bank
);
535 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
536 return ERROR_FLASH_OPERATION_FAILED
;
541 static int str9xpec_set_address(struct flash_bank
*bank
, uint8_t sector
)
543 struct jtag_tap
*tap
;
544 struct scan_field field
;
545 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
547 tap
= str9xpec_info
->tap
;
549 /* set flash controller address */
550 str9xpec_set_instr(tap
, ISC_ADDRESS_SHIFT
, TAP_IRPAUSE
);
554 field
.out_value
= §or
;
555 field
.in_value
= NULL
;
557 jtag_add_dr_scan(1, &field
, jtag_get_end_state());
562 static int str9xpec_write(struct flash_bank
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
564 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
565 uint32_t dwords_remaining
= (count
/ 8);
566 uint32_t bytes_remaining
= (count
& 0x00000007);
567 uint32_t bytes_written
= 0;
569 uint32_t check_address
= offset
;
570 struct jtag_tap
*tap
;
571 struct scan_field field
;
574 int first_sector
= 0;
577 tap
= str9xpec_info
->tap
;
579 if (!str9xpec_info
->isc_enable
) {
580 str9xpec_isc_enable(bank
);
583 if (!str9xpec_info
->isc_enable
) {
584 return ERROR_FLASH_OPERATION_FAILED
;
589 LOG_WARNING("offset 0x%" PRIx32
" breaks required 8-byte alignment", offset
);
590 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
593 for (i
= 0; i
< bank
->num_sectors
; i
++)
595 uint32_t sec_start
= bank
->sectors
[i
].offset
;
596 uint32_t sec_end
= sec_start
+ bank
->sectors
[i
].size
;
598 /* check if destination falls within the current sector */
599 if ((check_address
>= sec_start
) && (check_address
< sec_end
))
601 /* check if destination ends in the current sector */
602 if (offset
+ count
< sec_end
)
603 check_address
= offset
+ count
;
605 check_address
= sec_end
;
608 if ((offset
>= sec_start
) && (offset
< sec_end
)) {
612 if ((offset
+ count
>= sec_start
) && (offset
+ count
< sec_end
)) {
617 if (check_address
!= offset
+ count
)
618 return ERROR_FLASH_DST_OUT_OF_BANK
;
620 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector
, last_sector
);
622 scanbuf
= calloc(DIV_ROUND_UP(64, 8), 1);
624 LOG_DEBUG("ISC_PROGRAM");
626 for (i
= first_sector
; i
<= last_sector
; i
++)
628 str9xpec_set_address(bank
, str9xpec_info
->sector_bits
[i
]);
630 dwords_remaining
= dwords_remaining
< (bank
->sectors
[i
].size
/8) ? dwords_remaining
: (bank
->sectors
[i
].size
/8);
632 while (dwords_remaining
> 0)
634 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
638 field
.out_value
= (buffer
+ bytes_written
);
639 field
.in_value
= NULL
;
641 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
643 /* small delay before polling */
646 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
651 field
.out_value
= NULL
;
652 field
.in_value
= scanbuf
;
654 jtag_add_dr_scan(1, &field
, jtag_get_end_state());
655 jtag_execute_queue();
657 status
= buf_get_u32(scanbuf
, 0, 8);
659 } while (!(status
& ISC_STATUS_BUSY
));
661 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
662 return ERROR_FLASH_OPERATION_FAILED
;
664 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
665 return ERROR_FLASH_OPERATION_FAILED; */
674 uint8_t last_dword
[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
677 while (bytes_remaining
> 0)
679 last_dword
[i
++] = *(buffer
+ bytes_written
);
684 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
688 field
.out_value
= last_dword
;
689 field
.in_value
= NULL
;
691 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
693 /* small delay before polling */
696 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
701 field
.out_value
= NULL
;
702 field
.in_value
= scanbuf
;
704 jtag_add_dr_scan(1, &field
, jtag_get_end_state());
705 jtag_execute_queue();
707 status
= buf_get_u32(scanbuf
, 0, 8);
709 } while (!(status
& ISC_STATUS_BUSY
));
711 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
712 return ERROR_FLASH_OPERATION_FAILED
;
714 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
715 return ERROR_FLASH_OPERATION_FAILED; */
720 str9xpec_isc_disable(bank
);
725 static int str9xpec_probe(struct flash_bank
*bank
)
730 COMMAND_HANDLER(str9xpec_handle_part_id_command
)
732 struct scan_field field
;
733 uint8_t *buffer
= NULL
;
734 struct jtag_tap
*tap
;
736 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
739 return ERROR_COMMAND_SYNTAX_ERROR
;
741 struct flash_bank
*bank
;
742 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
743 if (ERROR_OK
!= retval
)
746 str9xpec_info
= bank
->driver_priv
;
747 tap
= str9xpec_info
->tap
;
749 buffer
= calloc(DIV_ROUND_UP(32, 8), 1);
751 str9xpec_set_instr(tap
, ISC_IDCODE
, TAP_IRPAUSE
);
755 field
.out_value
= NULL
;
756 field
.in_value
= buffer
;
758 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
759 jtag_execute_queue();
761 idcode
= buf_get_u32(buffer
, 0, 32);
763 command_print(CMD_CTX
, "str9xpec part id: 0x%8.8" PRIx32
"", idcode
);
770 static int str9xpec_erase_check(struct flash_bank
*bank
)
772 return str9xpec_blank_check(bank
, 0, bank
->num_sectors
- 1);
775 static int str9xpec_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
777 snprintf(buf
, buf_size
, "str9xpec flash driver info");
781 COMMAND_HANDLER(str9xpec_handle_flash_options_read_command
)
784 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
788 command_print(CMD_CTX
, "str9xpec options_read <bank>");
792 struct flash_bank
*bank
;
793 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
794 if (ERROR_OK
!= retval
)
797 str9xpec_info
= bank
->driver_priv
;
799 status
= str9xpec_read_config(bank
);
801 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
802 return ERROR_FLASH_OPERATION_FAILED
;
805 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1))
806 command_print(CMD_CTX
, "CS Map: bank1");
808 command_print(CMD_CTX
, "CS Map: bank0");
811 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_OTPBIT
, 1))
812 command_print(CMD_CTX
, "OTP Lock: OTP Locked");
814 command_print(CMD_CTX
, "OTP Lock: OTP Unlocked");
817 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1))
818 command_print(CMD_CTX
, "LVD Threshold: 2.7v");
820 command_print(CMD_CTX
, "LVD Threshold: 2.4v");
822 /* LVD reset warning */
823 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1))
824 command_print(CMD_CTX
, "LVD Reset Warning: VDD or VDDQ Inputs");
826 command_print(CMD_CTX
, "LVD Reset Warning: VDD Input Only");
828 /* LVD reset select */
829 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1))
830 command_print(CMD_CTX
, "LVD Reset Selection: VDD or VDDQ Inputs");
832 command_print(CMD_CTX
, "LVD Reset Selection: VDD Input Only");
837 static int str9xpec_write_options(struct flash_bank
*bank
)
839 struct scan_field field
;
841 struct jtag_tap
*tap
;
842 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
844 str9xpec_info
= bank
->driver_priv
;
845 tap
= str9xpec_info
->tap
;
847 /* erase config options first */
848 status
= str9xpec_erase_area(bank
, 0xFE, 0xFE);
850 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
853 if (!str9xpec_info
->isc_enable
) {
854 str9xpec_isc_enable(bank
);
857 if (!str9xpec_info
->isc_enable
) {
858 return ISC_STATUS_ERROR
;
861 /* according to data 64th bit has to be set */
862 buf_set_u32(str9xpec_info
->options
, 63, 1, 1);
864 /* set option byte address */
865 str9xpec_set_address(bank
, 0x50);
867 /* execute ISC_PROGRAM command */
868 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
872 field
.out_value
= str9xpec_info
->options
;
873 field
.in_value
= NULL
;
875 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
877 /* small delay before polling */
880 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
885 field
.out_value
= NULL
;
886 field
.in_value
= &status
;
888 jtag_add_dr_scan(1, &field
, jtag_get_end_state());
889 jtag_execute_queue();
891 } while (!(status
& ISC_STATUS_BUSY
));
893 str9xpec_isc_disable(bank
);
898 COMMAND_HANDLER(str9xpec_handle_flash_options_write_command
)
904 command_print(CMD_CTX
, "str9xpec options_write <bank>");
908 struct flash_bank
*bank
;
909 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
910 if (ERROR_OK
!= retval
)
913 status
= str9xpec_write_options(bank
);
915 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
916 return ERROR_FLASH_OPERATION_FAILED
;
921 COMMAND_HANDLER(str9xpec_handle_flash_options_cmap_command
)
923 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
927 command_print(CMD_CTX
, "str9xpec options_cmap <bank> <bank0 | bank1>");
931 struct flash_bank
*bank
;
932 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
933 if (ERROR_OK
!= retval
)
936 str9xpec_info
= bank
->driver_priv
;
938 if (strcmp(CMD_ARGV
[1], "bank1") == 0)
940 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 1);
944 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 0);
950 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdthd_command
)
952 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
956 command_print(CMD_CTX
, "str9xpec options_lvdthd <bank> <2.4v | 2.7v>");
960 struct flash_bank
*bank
;
961 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
962 if (ERROR_OK
!= retval
)
965 str9xpec_info
= bank
->driver_priv
;
967 if (strcmp(CMD_ARGV
[1], "2.7v") == 0)
969 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 1);
973 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 0);
979 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdsel_command
)
981 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
985 command_print(CMD_CTX
, "str9xpec options_lvdsel <bank> <vdd | vdd_vddq>");
989 struct flash_bank
*bank
;
990 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
991 if (ERROR_OK
!= retval
)
994 str9xpec_info
= bank
->driver_priv
;
996 if (strcmp(CMD_ARGV
[1], "vdd_vddq") == 0)
998 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 1);
1002 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 0);
1008 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdwarn_command
)
1010 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
1014 command_print(CMD_CTX
, "str9xpec options_lvdwarn <bank> <vdd | vdd_vddq>");
1018 struct flash_bank
*bank
;
1019 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1020 if (ERROR_OK
!= retval
)
1023 str9xpec_info
= bank
->driver_priv
;
1025 if (strcmp(CMD_ARGV
[1], "vdd_vddq") == 0)
1027 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 1);
1031 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 0);
1037 COMMAND_HANDLER(str9xpec_handle_flash_lock_command
)
1043 command_print(CMD_CTX
, "str9xpec lock <bank>");
1047 struct flash_bank
*bank
;
1048 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1049 if (ERROR_OK
!= retval
)
1052 status
= str9xpec_lock_device(bank
);
1054 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1055 return ERROR_FLASH_OPERATION_FAILED
;
1060 COMMAND_HANDLER(str9xpec_handle_flash_unlock_command
)
1066 command_print(CMD_CTX
, "str9xpec unlock <bank>");
1070 struct flash_bank
*bank
;
1071 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1072 if (ERROR_OK
!= retval
)
1075 status
= str9xpec_unlock_device(bank
);
1077 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1078 return ERROR_FLASH_OPERATION_FAILED
;
1083 COMMAND_HANDLER(str9xpec_handle_flash_enable_turbo_command
)
1085 struct jtag_tap
*tap0
;
1086 struct jtag_tap
*tap1
;
1087 struct jtag_tap
*tap2
;
1088 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
1092 command_print(CMD_CTX
, "str9xpec enable_turbo <bank>");
1096 struct flash_bank
*bank
;
1097 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1098 if (ERROR_OK
!= retval
)
1101 str9xpec_info
= bank
->driver_priv
;
1103 tap0
= str9xpec_info
->tap
;
1105 /* remove arm core from chain - enter turbo mode */
1106 tap1
= tap0
->next_tap
;
1109 /* things are *WRONG* */
1110 command_print(CMD_CTX
,"**STR9FLASH** (tap1) invalid chain?");
1113 tap2
= tap1
->next_tap
;
1116 /* things are *WRONG* */
1117 command_print(CMD_CTX
,"**STR9FLASH** (tap2) invalid chain?");
1121 /* enable turbo mode - TURBO-PROG-ENABLE */
1122 str9xpec_set_instr(tap2
, 0xD, TAP_IDLE
);
1123 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
1126 /* modify scan chain - str9 core has been removed */
1132 COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command
)
1134 struct jtag_tap
*tap
;
1135 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
1139 command_print(CMD_CTX
, "str9xpec disable_turbo <bank>");
1143 struct flash_bank
*bank
;
1144 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1145 if (ERROR_OK
!= retval
)
1148 str9xpec_info
= bank
->driver_priv
;
1149 tap
= str9xpec_info
->tap
;
1154 /* exit turbo mode via RESET */
1155 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IDLE
);
1157 jtag_execute_queue();
1159 /* restore previous scan chain */
1160 if (tap
->next_tap
) {
1161 tap
->next_tap
->enabled
= 1;
1167 static const struct command_registration str9xpec_config_command_handlers
[] = {
1169 .name
= "enable_turbo",
1170 .handler
= str9xpec_handle_flash_enable_turbo_command
,
1171 .mode
= COMMAND_EXEC
,
1172 .help
= "enable str9xpec turbo mode",
1175 .name
= "disable_turbo",
1176 .handler
= str9xpec_handle_flash_disable_turbo_command
,
1177 .mode
= COMMAND_EXEC
,
1178 .help
= "disable str9xpec turbo mode",
1181 .name
= "options_cmap",
1182 .handler
= str9xpec_handle_flash_options_cmap_command
,
1183 .mode
= COMMAND_EXEC
,
1184 .help
= "configure str9xpec boot sector",
1187 .name
= "options_lvdthd",
1188 .handler
= str9xpec_handle_flash_options_lvdthd_command
,
1189 .mode
= COMMAND_EXEC
,
1190 .help
= "configure str9xpec lvd threshold",
1193 .name
= "options_lvdsel",
1194 .handler
= str9xpec_handle_flash_options_lvdsel_command
,
1195 .mode
= COMMAND_EXEC
,
1196 .help
= "configure str9xpec lvd selection",
1199 .name
= "options_lvdwarn",
1200 .handler
= str9xpec_handle_flash_options_lvdwarn_command
,
1201 .mode
= COMMAND_EXEC
,
1202 .help
= "configure str9xpec lvd warning",
1205 .name
= "options_read",
1206 .handler
= str9xpec_handle_flash_options_read_command
,
1207 .mode
= COMMAND_EXEC
,
1208 .help
= "read str9xpec options",
1211 .name
= "options_write",
1212 .handler
= str9xpec_handle_flash_options_write_command
,
1213 .mode
= COMMAND_EXEC
,
1214 .help
= "write str9xpec options",
1218 .handler
= str9xpec_handle_flash_lock_command
,
1219 .mode
= COMMAND_EXEC
,
1220 .help
= "lock str9xpec device",
1224 .handler
= str9xpec_handle_flash_unlock_command
,
1225 .mode
= COMMAND_EXEC
,
1226 .help
= "unlock str9xpec device",
1230 .handler
= str9xpec_handle_part_id_command
,
1231 .mode
= COMMAND_EXEC
,
1232 .help
= "print part id of str9xpec flash bank <num>",
1234 COMMAND_REGISTRATION_DONE
1236 static const struct command_registration str9xpec_command_handlers
[] = {
1239 .mode
= COMMAND_ANY
,
1240 .help
= "str9xpec flash command group",
1241 .chain
= str9xpec_config_command_handlers
,
1243 COMMAND_REGISTRATION_DONE
1246 struct flash_driver str9xpec_flash
= {
1248 .commands
= str9xpec_command_handlers
,
1249 .flash_bank_command
= &str9xpec_flash_bank_command
,
1250 .erase
= &str9xpec_erase
,
1251 .protect
= &str9xpec_protect
,
1252 .write
= &str9xpec_write
,
1253 .probe
= &str9xpec_probe
,
1254 .auto_probe
= &str9xpec_probe
,
1255 .erase_check
= &str9xpec_erase_check
,
1256 .protect_check
= &str9xpec_protect_check
,
1257 .info
= &str9xpec_info
,