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 <target/arm7_9_common.h>
33 #define ISC_IDCODE 0xFE
34 #define ISC_MFG_READ 0x4C
35 #define ISC_CONFIGURATION 0x07
36 #define ISC_ENABLE 0x0C
37 #define ISC_DISABLE 0x0F
39 #define ISC_ADDRESS_SHIFT 0x11
40 #define ISC_CLR_STATUS 0x13
41 #define ISC_PROGRAM 0x20
42 #define ISC_PROGRAM_SECURITY 0x22
43 #define ISC_PROGRAM_UC 0x23
44 #define ISC_ERASE 0x30
46 #define ISC_BLANK_CHECK 0x60
48 /* ISC_DEFAULT bit definitions */
50 #define ISC_STATUS_SECURITY 0x40
51 #define ISC_STATUS_INT_ERROR 0x30
52 #define ISC_STATUS_MODE 0x08
53 #define ISC_STATUS_BUSY 0x04
54 #define ISC_STATUS_ERROR 0x03
56 /* Option bytes definitions */
58 #define STR9XPEC_OPT_CSMAPBIT 48
59 #define STR9XPEC_OPT_LVDTHRESBIT 49
60 #define STR9XPEC_OPT_LVDSELBIT 50
61 #define STR9XPEC_OPT_LVDWARNBIT 51
62 #define STR9XPEC_OPT_OTPBIT 63
64 enum str9xpec_status_codes
66 STR9XPEC_INVALID_COMMAND
= 1,
67 STR9XPEC_ISC_SUCCESS
= 2,
68 STR9XPEC_ISC_DISABLED
= 3,
69 STR9XPEC_ISC_INTFAIL
= 32,
72 struct str9xpec_flash_controller
75 uint32_t *sector_bits
;
81 static int str9xpec_erase_area(struct flash_bank
*bank
, int first
, int last
);
82 static int str9xpec_set_address(struct flash_bank
*bank
, uint8_t sector
);
83 static int str9xpec_write_options(struct flash_bank
*bank
);
85 static int str9xpec_set_instr(struct jtag_tap
*tap
, uint32_t new_instr
, tap_state_t end_state
)
88 return ERROR_TARGET_INVALID
;
91 if (buf_get_u32(tap
->cur_instr
, 0, tap
->ir_length
) != new_instr
)
93 struct scan_field field
;
95 field
.num_bits
= tap
->ir_length
;
96 void * t
= calloc(DIV_ROUND_UP(field
.num_bits
, 8), 1);
98 buf_set_u32(t
, 0, field
.num_bits
, new_instr
);
99 field
.in_value
= NULL
;
101 jtag_add_ir_scan(tap
, &field
, end_state
);
109 static uint8_t str9xpec_isc_status(struct jtag_tap
*tap
)
111 struct scan_field field
;
114 if (str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
) != ERROR_OK
)
115 return ISC_STATUS_ERROR
;
118 field
.out_value
= NULL
;
119 field
.in_value
= &status
;
122 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
123 jtag_execute_queue();
125 LOG_DEBUG("status: 0x%2.2x", status
);
127 if (status
& ISC_STATUS_SECURITY
)
128 LOG_INFO("Device Security Bit Set");
133 static int str9xpec_isc_enable(struct flash_bank
*bank
)
136 struct jtag_tap
*tap
;
137 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
139 tap
= str9xpec_info
->tap
;
141 if (str9xpec_info
->isc_enable
)
145 if (str9xpec_set_instr(tap
, ISC_ENABLE
, TAP_IDLE
) != ERROR_OK
)
146 return ERROR_TARGET_INVALID
;
148 /* check ISC status */
149 status
= str9xpec_isc_status(tap
);
150 if (status
& ISC_STATUS_MODE
)
152 /* we have entered isc mode */
153 str9xpec_info
->isc_enable
= 1;
154 LOG_DEBUG("ISC_MODE Enabled");
160 static int str9xpec_isc_disable(struct flash_bank
*bank
)
163 struct jtag_tap
*tap
;
164 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
166 tap
= str9xpec_info
->tap
;
168 if (!str9xpec_info
->isc_enable
)
171 if (str9xpec_set_instr(tap
, ISC_DISABLE
, TAP_IDLE
) != ERROR_OK
)
172 return ERROR_TARGET_INVALID
;
174 /* delay to handle aborts */
177 /* check ISC status */
178 status
= str9xpec_isc_status(tap
);
179 if (!(status
& ISC_STATUS_MODE
))
181 /* we have left isc mode */
182 str9xpec_info
->isc_enable
= 0;
183 LOG_DEBUG("ISC_MODE Disabled");
189 static int str9xpec_read_config(struct flash_bank
*bank
)
191 struct scan_field field
;
193 struct jtag_tap
*tap
;
195 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
197 tap
= str9xpec_info
->tap
;
199 LOG_DEBUG("ISC_CONFIGURATION");
201 /* execute ISC_CONFIGURATION command */
202 str9xpec_set_instr(tap
, ISC_CONFIGURATION
, TAP_IRPAUSE
);
205 field
.out_value
= NULL
;
206 field
.in_value
= str9xpec_info
->options
;
209 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
210 jtag_execute_queue();
212 status
= str9xpec_isc_status(tap
);
217 static int str9xpec_build_block_list(struct flash_bank
*bank
)
219 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
223 int b0_sectors
= 0, b1_sectors
= 0;
225 int b1_size
= 0x2000;
249 LOG_ERROR("BUG: unknown bank->size encountered");
253 num_sectors
= b0_sectors
+ b1_sectors
;
255 bank
->num_sectors
= num_sectors
;
256 bank
->sectors
= malloc(sizeof(struct flash_sector
) * num_sectors
);
257 str9xpec_info
->sector_bits
= malloc(sizeof(uint32_t) * num_sectors
);
261 for (i
= 0; i
< b0_sectors
; i
++)
263 bank
->sectors
[num_sectors
].offset
= offset
;
264 bank
->sectors
[num_sectors
].size
= 0x10000;
265 offset
+= bank
->sectors
[i
].size
;
266 bank
->sectors
[num_sectors
].is_erased
= -1;
267 bank
->sectors
[num_sectors
].is_protected
= 1;
268 str9xpec_info
->sector_bits
[num_sectors
++] = i
;
271 for (i
= 0; i
< b1_sectors
; i
++)
273 bank
->sectors
[num_sectors
].offset
= offset
;
274 bank
->sectors
[num_sectors
].size
= b1_size
;
275 offset
+= bank
->sectors
[i
].size
;
276 bank
->sectors
[num_sectors
].is_erased
= -1;
277 bank
->sectors
[num_sectors
].is_protected
= 1;
278 str9xpec_info
->sector_bits
[num_sectors
++] = i
+ 32;
284 /* flash bank str9x <base> <size> 0 0 <target#>
286 FLASH_BANK_COMMAND_HANDLER(str9xpec_flash_bank_command
)
288 struct str9xpec_flash_controller
*str9xpec_info
;
289 struct arm
*armv4_5
= NULL
;
290 struct arm7_9_common
*arm7_9
= NULL
;
291 struct arm_jtag
*jtag_info
= NULL
;
295 LOG_WARNING("incomplete flash_bank str9x configuration");
296 return ERROR_FLASH_BANK_INVALID
;
299 str9xpec_info
= malloc(sizeof(struct str9xpec_flash_controller
));
300 bank
->driver_priv
= str9xpec_info
;
302 /* REVISIT verify that the jtag position of flash controller is
303 * right after *THIS* core, which must be a STR9xx core ...
305 armv4_5
= bank
->target
->arch_info
;
306 arm7_9
= armv4_5
->arch_info
;
307 jtag_info
= &arm7_9
->jtag_info
;
309 /* The core is the next tap after the flash controller in the chain */
310 str9xpec_info
->tap
= jtag_tap_by_position(jtag_info
->tap
->abs_chain_position
- 1);
311 str9xpec_info
->isc_enable
= 0;
313 str9xpec_build_block_list(bank
);
315 /* clear option byte register */
316 buf_set_u32(str9xpec_info
->options
, 0, 64, 0);
321 static int str9xpec_blank_check(struct flash_bank
*bank
, int first
, int last
)
323 struct scan_field field
;
325 struct jtag_tap
*tap
;
327 uint8_t *buffer
= NULL
;
329 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
331 tap
= str9xpec_info
->tap
;
333 if (!str9xpec_info
->isc_enable
) {
334 str9xpec_isc_enable(bank
);
337 if (!str9xpec_info
->isc_enable
) {
338 return ERROR_FLASH_OPERATION_FAILED
;
341 buffer
= calloc(DIV_ROUND_UP(64, 8), 1);
343 LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first
, last
);
345 for (i
= first
; i
<= last
; i
++) {
346 buf_set_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1, 1);
349 /* execute ISC_BLANK_CHECK command */
350 str9xpec_set_instr(tap
, ISC_BLANK_CHECK
, TAP_IRPAUSE
);
353 field
.out_value
= buffer
;
354 field
.in_value
= NULL
;
356 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
357 jtag_add_sleep(40000);
359 /* read blank check result */
361 field
.out_value
= NULL
;
362 field
.in_value
= buffer
;
364 jtag_add_dr_scan(tap
, 1, &field
, TAP_IRPAUSE
);
365 jtag_execute_queue();
367 status
= str9xpec_isc_status(tap
);
369 for (i
= first
; i
<= last
; i
++)
371 if (buf_get_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1))
372 bank
->sectors
[i
].is_erased
= 0;
374 bank
->sectors
[i
].is_erased
= 1;
379 str9xpec_isc_disable(bank
);
381 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
382 return ERROR_FLASH_OPERATION_FAILED
;
386 static int str9xpec_protect_check(struct flash_bank
*bank
)
391 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
393 status
= str9xpec_read_config(bank
);
395 for (i
= 0; i
< bank
->num_sectors
; i
++)
397 if (buf_get_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1))
398 bank
->sectors
[i
].is_protected
= 1;
400 bank
->sectors
[i
].is_protected
= 0;
403 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
404 return ERROR_FLASH_OPERATION_FAILED
;
408 static int str9xpec_erase_area(struct flash_bank
*bank
, int first
, int last
)
410 struct scan_field field
;
412 struct jtag_tap
*tap
;
414 uint8_t *buffer
= NULL
;
416 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
418 tap
= str9xpec_info
->tap
;
420 if (!str9xpec_info
->isc_enable
) {
421 str9xpec_isc_enable(bank
);
424 if (!str9xpec_info
->isc_enable
) {
425 return ISC_STATUS_ERROR
;
428 buffer
= calloc(DIV_ROUND_UP(64, 8), 1);
430 LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first
, last
);
432 /* last bank: 0xFF signals a full erase (unlock complete device) */
433 /* last bank: 0xFE signals a option byte erase */
436 for (i
= 0; i
< 64; i
++) {
437 buf_set_u32(buffer
, i
, 1, 1);
440 else if (last
== 0xFE)
442 buf_set_u32(buffer
, 49, 1, 1);
446 for (i
= first
; i
<= last
; i
++) {
447 buf_set_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1, 1);
451 LOG_DEBUG("ISC_ERASE");
453 /* execute ISC_ERASE command */
454 str9xpec_set_instr(tap
, ISC_ERASE
, TAP_IRPAUSE
);
457 field
.out_value
= buffer
;
458 field
.in_value
= NULL
;
460 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
461 jtag_execute_queue();
465 /* wait for erase completion */
466 while (!((status
= str9xpec_isc_status(tap
)) & ISC_STATUS_BUSY
)) {
472 str9xpec_isc_disable(bank
);
477 static int str9xpec_erase(struct flash_bank
*bank
, int first
, int last
)
481 status
= str9xpec_erase_area(bank
, first
, last
);
483 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
484 return ERROR_FLASH_OPERATION_FAILED
;
489 static int str9xpec_lock_device(struct flash_bank
*bank
)
491 struct scan_field field
;
493 struct jtag_tap
*tap
;
494 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
496 str9xpec_info
= bank
->driver_priv
;
497 tap
= str9xpec_info
->tap
;
499 if (!str9xpec_info
->isc_enable
) {
500 str9xpec_isc_enable(bank
);
503 if (!str9xpec_info
->isc_enable
) {
504 return ISC_STATUS_ERROR
;
507 /* set security address */
508 str9xpec_set_address(bank
, 0x80);
510 /* execute ISC_PROGRAM command */
511 str9xpec_set_instr(tap
, ISC_PROGRAM_SECURITY
, TAP_IDLE
);
513 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
517 field
.out_value
= NULL
;
518 field
.in_value
= &status
;
520 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
521 jtag_execute_queue();
523 } while (!(status
& ISC_STATUS_BUSY
));
525 str9xpec_isc_disable(bank
);
530 static int str9xpec_unlock_device(struct flash_bank
*bank
)
534 status
= str9xpec_erase_area(bank
, 0, 255);
539 static int str9xpec_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
544 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
546 status
= str9xpec_read_config(bank
);
548 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
549 return ERROR_FLASH_OPERATION_FAILED
;
551 LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first
, last
);
553 /* last bank: 0xFF signals a full device protect */
558 status
= str9xpec_lock_device(bank
);
562 /* perform full erase to unlock device */
563 status
= str9xpec_unlock_device(bank
);
568 for (i
= first
; i
<= last
; i
++)
571 buf_set_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1, 1);
573 buf_set_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1, 0);
576 status
= str9xpec_write_options(bank
);
579 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
580 return ERROR_FLASH_OPERATION_FAILED
;
585 static int str9xpec_set_address(struct flash_bank
*bank
, uint8_t sector
)
587 struct jtag_tap
*tap
;
588 struct scan_field field
;
589 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
591 tap
= str9xpec_info
->tap
;
593 /* set flash controller address */
594 str9xpec_set_instr(tap
, ISC_ADDRESS_SHIFT
, TAP_IRPAUSE
);
597 field
.out_value
= §or
;
598 field
.in_value
= NULL
;
600 jtag_add_dr_scan(tap
, 1, &field
, TAP_IRPAUSE
);
605 static int str9xpec_write(struct flash_bank
*bank
, uint8_t *buffer
,
606 uint32_t offset
, uint32_t count
)
608 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
609 uint32_t dwords_remaining
= (count
/ 8);
610 uint32_t bytes_remaining
= (count
& 0x00000007);
611 uint32_t bytes_written
= 0;
613 uint32_t check_address
= offset
;
614 struct jtag_tap
*tap
;
615 struct scan_field field
;
618 int first_sector
= 0;
621 tap
= str9xpec_info
->tap
;
623 if (!str9xpec_info
->isc_enable
) {
624 str9xpec_isc_enable(bank
);
627 if (!str9xpec_info
->isc_enable
) {
628 return ERROR_FLASH_OPERATION_FAILED
;
633 LOG_WARNING("offset 0x%" PRIx32
" breaks required 8-byte alignment", offset
);
634 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
637 for (i
= 0; i
< bank
->num_sectors
; i
++)
639 uint32_t sec_start
= bank
->sectors
[i
].offset
;
640 uint32_t sec_end
= sec_start
+ bank
->sectors
[i
].size
;
642 /* check if destination falls within the current sector */
643 if ((check_address
>= sec_start
) && (check_address
< sec_end
))
645 /* check if destination ends in the current sector */
646 if (offset
+ count
< sec_end
)
647 check_address
= offset
+ count
;
649 check_address
= sec_end
;
652 if ((offset
>= sec_start
) && (offset
< sec_end
)) {
656 if ((offset
+ count
>= sec_start
) && (offset
+ count
< sec_end
)) {
661 if (check_address
!= offset
+ count
)
662 return ERROR_FLASH_DST_OUT_OF_BANK
;
664 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector
, last_sector
);
666 scanbuf
= calloc(DIV_ROUND_UP(64, 8), 1);
668 LOG_DEBUG("ISC_PROGRAM");
670 for (i
= first_sector
; i
<= last_sector
; i
++)
672 str9xpec_set_address(bank
, str9xpec_info
->sector_bits
[i
]);
674 dwords_remaining
= dwords_remaining
< (bank
->sectors
[i
].size
/8)
675 ? dwords_remaining
: (bank
->sectors
[i
].size
/8);
677 while (dwords_remaining
> 0)
679 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
682 field
.out_value
= (buffer
+ bytes_written
);
683 field
.in_value
= NULL
;
685 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
687 /* small delay before polling */
690 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
694 field
.out_value
= NULL
;
695 field
.in_value
= scanbuf
;
697 jtag_add_dr_scan(tap
, 1, &field
, TAP_IRPAUSE
);
698 jtag_execute_queue();
700 status
= buf_get_u32(scanbuf
, 0, 8);
702 } while (!(status
& ISC_STATUS_BUSY
));
704 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
705 return ERROR_FLASH_OPERATION_FAILED
;
707 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
708 return ERROR_FLASH_OPERATION_FAILED; */
717 uint8_t last_dword
[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
720 while (bytes_remaining
> 0)
722 last_dword
[i
++] = *(buffer
+ bytes_written
);
727 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
730 field
.out_value
= last_dword
;
731 field
.in_value
= NULL
;
733 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
735 /* small delay before polling */
738 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
742 field
.out_value
= NULL
;
743 field
.in_value
= scanbuf
;
745 jtag_add_dr_scan(tap
, 1, &field
, TAP_IRPAUSE
);
746 jtag_execute_queue();
748 status
= buf_get_u32(scanbuf
, 0, 8);
750 } while (!(status
& ISC_STATUS_BUSY
));
752 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
753 return ERROR_FLASH_OPERATION_FAILED
;
755 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
756 return ERROR_FLASH_OPERATION_FAILED; */
761 str9xpec_isc_disable(bank
);
766 static int str9xpec_probe(struct flash_bank
*bank
)
771 COMMAND_HANDLER(str9xpec_handle_part_id_command
)
773 struct scan_field field
;
774 uint8_t *buffer
= NULL
;
775 struct jtag_tap
*tap
;
777 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
780 return ERROR_COMMAND_SYNTAX_ERROR
;
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
;
788 tap
= str9xpec_info
->tap
;
790 buffer
= calloc(DIV_ROUND_UP(32, 8), 1);
792 str9xpec_set_instr(tap
, ISC_IDCODE
, TAP_IRPAUSE
);
795 field
.out_value
= NULL
;
796 field
.in_value
= buffer
;
798 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
799 jtag_execute_queue();
801 idcode
= buf_get_u32(buffer
, 0, 32);
803 command_print(CMD_CTX
, "str9xpec part id: 0x%8.8" PRIx32
"", idcode
);
810 static int str9xpec_erase_check(struct flash_bank
*bank
)
812 return str9xpec_blank_check(bank
, 0, bank
->num_sectors
- 1);
815 static int get_str9xpec_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
817 snprintf(buf
, buf_size
, "str9xpec flash driver info");
821 COMMAND_HANDLER(str9xpec_handle_flash_options_read_command
)
824 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
828 command_print(CMD_CTX
, "str9xpec options_read <bank>");
832 struct flash_bank
*bank
;
833 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
834 if (ERROR_OK
!= retval
)
837 str9xpec_info
= bank
->driver_priv
;
839 status
= str9xpec_read_config(bank
);
841 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
842 return ERROR_FLASH_OPERATION_FAILED
;
845 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1))
846 command_print(CMD_CTX
, "CS Map: bank1");
848 command_print(CMD_CTX
, "CS Map: bank0");
851 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_OTPBIT
, 1))
852 command_print(CMD_CTX
, "OTP Lock: OTP Locked");
854 command_print(CMD_CTX
, "OTP Lock: OTP Unlocked");
857 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1))
858 command_print(CMD_CTX
, "LVD Threshold: 2.7v");
860 command_print(CMD_CTX
, "LVD Threshold: 2.4v");
862 /* LVD reset warning */
863 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1))
864 command_print(CMD_CTX
, "LVD Reset Warning: VDD or VDDQ Inputs");
866 command_print(CMD_CTX
, "LVD Reset Warning: VDD Input Only");
868 /* LVD reset select */
869 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1))
870 command_print(CMD_CTX
, "LVD Reset Selection: VDD or VDDQ Inputs");
872 command_print(CMD_CTX
, "LVD Reset Selection: VDD Input Only");
877 static int str9xpec_write_options(struct flash_bank
*bank
)
879 struct scan_field field
;
881 struct jtag_tap
*tap
;
882 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
884 str9xpec_info
= bank
->driver_priv
;
885 tap
= str9xpec_info
->tap
;
887 /* erase config options first */
888 status
= str9xpec_erase_area(bank
, 0xFE, 0xFE);
890 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
893 if (!str9xpec_info
->isc_enable
) {
894 str9xpec_isc_enable(bank
);
897 if (!str9xpec_info
->isc_enable
) {
898 return ISC_STATUS_ERROR
;
901 /* according to data 64th bit has to be set */
902 buf_set_u32(str9xpec_info
->options
, 63, 1, 1);
904 /* set option byte address */
905 str9xpec_set_address(bank
, 0x50);
907 /* execute ISC_PROGRAM command */
908 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
911 field
.out_value
= str9xpec_info
->options
;
912 field
.in_value
= NULL
;
914 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
916 /* small delay before polling */
919 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
923 field
.out_value
= NULL
;
924 field
.in_value
= &status
;
926 jtag_add_dr_scan(tap
, 1, &field
, TAP_IRPAUSE
);
927 jtag_execute_queue();
929 } while (!(status
& ISC_STATUS_BUSY
));
931 str9xpec_isc_disable(bank
);
936 COMMAND_HANDLER(str9xpec_handle_flash_options_write_command
)
942 command_print(CMD_CTX
, "str9xpec options_write <bank>");
946 struct flash_bank
*bank
;
947 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
948 if (ERROR_OK
!= retval
)
951 status
= str9xpec_write_options(bank
);
953 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
954 return ERROR_FLASH_OPERATION_FAILED
;
956 command_print(CMD_CTX
, "str9xpec write options complete.\n"
957 "INFO: a reset or power cycle is required "
958 "for the new settings to take effect.");
963 COMMAND_HANDLER(str9xpec_handle_flash_options_cmap_command
)
965 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
969 command_print(CMD_CTX
, "str9xpec options_cmap <bank> <bank0 | bank1>");
973 struct flash_bank
*bank
;
974 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
975 if (ERROR_OK
!= retval
)
978 str9xpec_info
= bank
->driver_priv
;
980 if (strcmp(CMD_ARGV
[1], "bank1") == 0)
982 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 1);
986 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 0);
992 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdthd_command
)
994 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
998 command_print(CMD_CTX
, "str9xpec options_lvdthd <bank> <2.4v | 2.7v>");
1002 struct flash_bank
*bank
;
1003 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1004 if (ERROR_OK
!= retval
)
1007 str9xpec_info
= bank
->driver_priv
;
1009 if (strcmp(CMD_ARGV
[1], "2.7v") == 0)
1011 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 1);
1015 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 0);
1021 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdsel_command
)
1023 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
1027 command_print(CMD_CTX
, "str9xpec options_lvdsel <bank> <vdd | vdd_vddq>");
1031 struct flash_bank
*bank
;
1032 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1033 if (ERROR_OK
!= retval
)
1036 str9xpec_info
= bank
->driver_priv
;
1038 if (strcmp(CMD_ARGV
[1], "vdd_vddq") == 0)
1040 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 1);
1044 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 0);
1050 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdwarn_command
)
1052 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
1056 command_print(CMD_CTX
, "str9xpec options_lvdwarn <bank> <vdd | vdd_vddq>");
1060 struct flash_bank
*bank
;
1061 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1062 if (ERROR_OK
!= retval
)
1065 str9xpec_info
= bank
->driver_priv
;
1067 if (strcmp(CMD_ARGV
[1], "vdd_vddq") == 0)
1069 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 1);
1073 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 0);
1079 COMMAND_HANDLER(str9xpec_handle_flash_lock_command
)
1085 command_print(CMD_CTX
, "str9xpec lock <bank>");
1089 struct flash_bank
*bank
;
1090 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1091 if (ERROR_OK
!= retval
)
1094 status
= str9xpec_lock_device(bank
);
1096 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1097 return ERROR_FLASH_OPERATION_FAILED
;
1102 COMMAND_HANDLER(str9xpec_handle_flash_unlock_command
)
1108 command_print(CMD_CTX
, "str9xpec unlock <bank>");
1112 struct flash_bank
*bank
;
1113 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1114 if (ERROR_OK
!= retval
)
1117 status
= str9xpec_unlock_device(bank
);
1119 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1120 return ERROR_FLASH_OPERATION_FAILED
;
1122 command_print(CMD_CTX
, "str9xpec unlocked.\n"
1123 "INFO: a reset or power cycle is required "
1124 "for the new settings to take effect.");
1129 COMMAND_HANDLER(str9xpec_handle_flash_enable_turbo_command
)
1131 struct jtag_tap
*tap0
;
1132 struct jtag_tap
*tap1
;
1133 struct jtag_tap
*tap2
;
1134 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
1138 command_print(CMD_CTX
, "str9xpec enable_turbo <bank>");
1142 struct flash_bank
*bank
;
1143 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1144 if (ERROR_OK
!= retval
)
1147 str9xpec_info
= bank
->driver_priv
;
1149 tap0
= str9xpec_info
->tap
;
1151 /* remove arm core from chain - enter turbo mode */
1152 tap1
= tap0
->next_tap
;
1155 /* things are *WRONG* */
1156 command_print(CMD_CTX
,"**STR9FLASH** (tap1) invalid chain?");
1159 tap2
= tap1
->next_tap
;
1162 /* things are *WRONG* */
1163 command_print(CMD_CTX
,"**STR9FLASH** (tap2) invalid chain?");
1167 /* enable turbo mode - TURBO-PROG-ENABLE */
1168 str9xpec_set_instr(tap2
, 0xD, TAP_IDLE
);
1169 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
1172 /* modify scan chain - str9 core has been removed */
1178 COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command
)
1180 struct jtag_tap
*tap
;
1181 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
1185 command_print(CMD_CTX
, "str9xpec disable_turbo <bank>");
1189 struct flash_bank
*bank
;
1190 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1191 if (ERROR_OK
!= retval
)
1194 str9xpec_info
= bank
->driver_priv
;
1195 tap
= str9xpec_info
->tap
;
1200 /* exit turbo mode via RESET */
1201 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IDLE
);
1203 jtag_execute_queue();
1205 /* restore previous scan chain */
1206 if (tap
->next_tap
) {
1207 tap
->next_tap
->enabled
= 1;
1213 static const struct command_registration str9xpec_config_command_handlers
[] = {
1215 .name
= "enable_turbo",
1216 .handler
= str9xpec_handle_flash_enable_turbo_command
,
1217 .mode
= COMMAND_EXEC
,
1218 .help
= "enable str9xpec turbo mode",
1221 .name
= "disable_turbo",
1222 .handler
= str9xpec_handle_flash_disable_turbo_command
,
1223 .mode
= COMMAND_EXEC
,
1224 .help
= "disable str9xpec turbo mode",
1227 .name
= "options_cmap",
1228 .handler
= str9xpec_handle_flash_options_cmap_command
,
1229 .mode
= COMMAND_EXEC
,
1230 .help
= "configure str9xpec boot sector",
1233 .name
= "options_lvdthd",
1234 .handler
= str9xpec_handle_flash_options_lvdthd_command
,
1235 .mode
= COMMAND_EXEC
,
1236 .help
= "configure str9xpec lvd threshold",
1239 .name
= "options_lvdsel",
1240 .handler
= str9xpec_handle_flash_options_lvdsel_command
,
1241 .mode
= COMMAND_EXEC
,
1242 .help
= "configure str9xpec lvd selection",
1245 .name
= "options_lvdwarn",
1246 .handler
= str9xpec_handle_flash_options_lvdwarn_command
,
1247 .mode
= COMMAND_EXEC
,
1248 .help
= "configure str9xpec lvd warning",
1251 .name
= "options_read",
1252 .handler
= str9xpec_handle_flash_options_read_command
,
1253 .mode
= COMMAND_EXEC
,
1254 .help
= "read str9xpec options",
1257 .name
= "options_write",
1258 .handler
= str9xpec_handle_flash_options_write_command
,
1259 .mode
= COMMAND_EXEC
,
1260 .help
= "write str9xpec options",
1264 .handler
= str9xpec_handle_flash_lock_command
,
1265 .mode
= COMMAND_EXEC
,
1266 .help
= "lock str9xpec device",
1270 .handler
= str9xpec_handle_flash_unlock_command
,
1271 .mode
= COMMAND_EXEC
,
1272 .help
= "unlock str9xpec device",
1276 .handler
= str9xpec_handle_part_id_command
,
1277 .mode
= COMMAND_EXEC
,
1278 .help
= "print part id of str9xpec flash bank <num>",
1280 COMMAND_REGISTRATION_DONE
1283 static const struct command_registration str9xpec_command_handlers
[] = {
1286 .mode
= COMMAND_ANY
,
1287 .help
= "str9xpec flash command group",
1288 .chain
= str9xpec_config_command_handlers
,
1290 COMMAND_REGISTRATION_DONE
1293 struct flash_driver str9xpec_flash
= {
1295 .commands
= str9xpec_command_handlers
,
1296 .flash_bank_command
= str9xpec_flash_bank_command
,
1297 .erase
= str9xpec_erase
,
1298 .protect
= str9xpec_protect
,
1299 .write
= str9xpec_write
,
1300 .read
= default_flash_read
,
1301 .probe
= str9xpec_probe
,
1302 .auto_probe
= str9xpec_probe
,
1303 .erase_check
= str9xpec_erase_check
,
1304 .protect_check
= str9xpec_protect_check
,
1305 .info
= get_str9xpec_info
,