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>
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
{
65 STR9XPEC_INVALID_COMMAND
= 1,
66 STR9XPEC_ISC_SUCCESS
= 2,
67 STR9XPEC_ISC_DISABLED
= 3,
68 STR9XPEC_ISC_INTFAIL
= 32,
71 struct str9xpec_flash_controller
{
73 uint32_t *sector_bits
;
79 static int str9xpec_erase_area(struct flash_bank
*bank
, int first
, int last
);
80 static int str9xpec_set_address(struct flash_bank
*bank
, uint8_t sector
);
81 static int str9xpec_write_options(struct flash_bank
*bank
);
83 static int str9xpec_set_instr(struct jtag_tap
*tap
, uint32_t new_instr
, tap_state_t end_state
)
86 return ERROR_TARGET_INVALID
;
88 if (buf_get_u32(tap
->cur_instr
, 0, tap
->ir_length
) != new_instr
) {
89 struct scan_field field
;
91 field
.num_bits
= tap
->ir_length
;
92 void *t
= calloc(DIV_ROUND_UP(field
.num_bits
, 8), 1);
94 buf_set_u32(t
, 0, field
.num_bits
, new_instr
);
95 field
.in_value
= NULL
;
97 jtag_add_ir_scan(tap
, &field
, end_state
);
105 static uint8_t str9xpec_isc_status(struct jtag_tap
*tap
)
107 struct scan_field field
;
110 if (str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
) != ERROR_OK
)
111 return ISC_STATUS_ERROR
;
114 field
.out_value
= NULL
;
115 field
.in_value
= &status
;
118 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
119 jtag_execute_queue();
121 LOG_DEBUG("status: 0x%2.2x", status
);
123 if (status
& ISC_STATUS_SECURITY
)
124 LOG_INFO("Device Security Bit Set");
129 static int str9xpec_isc_enable(struct flash_bank
*bank
)
132 struct jtag_tap
*tap
;
133 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
135 tap
= str9xpec_info
->tap
;
137 if (str9xpec_info
->isc_enable
)
141 if (str9xpec_set_instr(tap
, ISC_ENABLE
, TAP_IDLE
) != ERROR_OK
)
142 return ERROR_TARGET_INVALID
;
144 /* check ISC status */
145 status
= str9xpec_isc_status(tap
);
146 if (status
& ISC_STATUS_MODE
) {
147 /* we have entered isc mode */
148 str9xpec_info
->isc_enable
= 1;
149 LOG_DEBUG("ISC_MODE Enabled");
155 static int str9xpec_isc_disable(struct flash_bank
*bank
)
158 struct jtag_tap
*tap
;
159 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
161 tap
= str9xpec_info
->tap
;
163 if (!str9xpec_info
->isc_enable
)
166 if (str9xpec_set_instr(tap
, ISC_DISABLE
, TAP_IDLE
) != ERROR_OK
)
167 return ERROR_TARGET_INVALID
;
169 /* delay to handle aborts */
172 /* check ISC status */
173 status
= str9xpec_isc_status(tap
);
174 if (!(status
& ISC_STATUS_MODE
)) {
175 /* we have left isc mode */
176 str9xpec_info
->isc_enable
= 0;
177 LOG_DEBUG("ISC_MODE Disabled");
183 static int str9xpec_read_config(struct flash_bank
*bank
)
185 struct scan_field field
;
187 struct jtag_tap
*tap
;
189 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
191 tap
= str9xpec_info
->tap
;
193 LOG_DEBUG("ISC_CONFIGURATION");
195 /* execute ISC_CONFIGURATION command */
196 str9xpec_set_instr(tap
, ISC_CONFIGURATION
, TAP_IRPAUSE
);
199 field
.out_value
= NULL
;
200 field
.in_value
= str9xpec_info
->options
;
202 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
203 jtag_execute_queue();
205 status
= str9xpec_isc_status(tap
);
210 static int str9xpec_build_block_list(struct flash_bank
*bank
)
212 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
216 int b0_sectors
= 0, b1_sectors
= 0;
218 int b1_size
= 0x2000;
220 switch (bank
->size
) {
241 LOG_ERROR("BUG: unknown bank->size encountered");
245 num_sectors
= b0_sectors
+ b1_sectors
;
247 bank
->num_sectors
= num_sectors
;
248 bank
->sectors
= malloc(sizeof(struct flash_sector
) * num_sectors
);
249 str9xpec_info
->sector_bits
= malloc(sizeof(uint32_t) * num_sectors
);
253 for (i
= 0; i
< b0_sectors
; i
++) {
254 bank
->sectors
[num_sectors
].offset
= offset
;
255 bank
->sectors
[num_sectors
].size
= 0x10000;
256 offset
+= bank
->sectors
[i
].size
;
257 bank
->sectors
[num_sectors
].is_erased
= -1;
258 bank
->sectors
[num_sectors
].is_protected
= 1;
259 str9xpec_info
->sector_bits
[num_sectors
++] = i
;
262 for (i
= 0; i
< b1_sectors
; i
++) {
263 bank
->sectors
[num_sectors
].offset
= offset
;
264 bank
->sectors
[num_sectors
].size
= b1_size
;
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
+ 32;
274 /* flash bank str9x <base> <size> 0 0 <target#>
276 FLASH_BANK_COMMAND_HANDLER(str9xpec_flash_bank_command
)
278 struct str9xpec_flash_controller
*str9xpec_info
;
279 struct arm
*arm
= NULL
;
280 struct arm7_9_common
*arm7_9
= NULL
;
281 struct arm_jtag
*jtag_info
= NULL
;
284 return ERROR_COMMAND_SYNTAX_ERROR
;
286 str9xpec_info
= malloc(sizeof(struct str9xpec_flash_controller
));
287 bank
->driver_priv
= str9xpec_info
;
289 /* REVISIT verify that the jtag position of flash controller is
290 * right after *THIS* core, which must be a STR9xx core ...
292 arm
= bank
->target
->arch_info
;
293 arm7_9
= arm
->arch_info
;
294 jtag_info
= &arm7_9
->jtag_info
;
296 /* The core is the next tap after the flash controller in the chain */
297 str9xpec_info
->tap
= jtag_tap_by_position(jtag_info
->tap
->abs_chain_position
- 1);
298 str9xpec_info
->isc_enable
= 0;
300 str9xpec_build_block_list(bank
);
302 /* clear option byte register */
303 buf_set_u32(str9xpec_info
->options
, 0, 64, 0);
308 static int str9xpec_blank_check(struct flash_bank
*bank
, int first
, int last
)
310 struct scan_field field
;
312 struct jtag_tap
*tap
;
314 uint8_t *buffer
= NULL
;
316 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
318 tap
= str9xpec_info
->tap
;
320 if (!str9xpec_info
->isc_enable
)
321 str9xpec_isc_enable(bank
);
323 if (!str9xpec_info
->isc_enable
)
324 return ERROR_FLASH_OPERATION_FAILED
;
326 buffer
= calloc(DIV_ROUND_UP(64, 8), 1);
328 LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first
, last
);
330 for (i
= first
; i
<= last
; i
++)
331 buf_set_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1, 1);
333 /* execute ISC_BLANK_CHECK command */
334 str9xpec_set_instr(tap
, ISC_BLANK_CHECK
, TAP_IRPAUSE
);
337 field
.out_value
= buffer
;
338 field
.in_value
= NULL
;
340 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
341 jtag_add_sleep(40000);
343 /* read blank check result */
345 field
.out_value
= NULL
;
346 field
.in_value
= buffer
;
348 jtag_add_dr_scan(tap
, 1, &field
, TAP_IRPAUSE
);
349 jtag_execute_queue();
351 status
= str9xpec_isc_status(tap
);
353 for (i
= first
; i
<= last
; i
++) {
354 if (buf_get_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1))
355 bank
->sectors
[i
].is_erased
= 0;
357 bank
->sectors
[i
].is_erased
= 1;
362 str9xpec_isc_disable(bank
);
364 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
365 return ERROR_FLASH_OPERATION_FAILED
;
369 static int str9xpec_protect_check(struct flash_bank
*bank
)
374 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
376 status
= str9xpec_read_config(bank
);
378 for (i
= 0; i
< bank
->num_sectors
; i
++) {
379 if (buf_get_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1))
380 bank
->sectors
[i
].is_protected
= 1;
382 bank
->sectors
[i
].is_protected
= 0;
385 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
386 return ERROR_FLASH_OPERATION_FAILED
;
390 static int str9xpec_erase_area(struct flash_bank
*bank
, int first
, int last
)
392 struct scan_field field
;
394 struct jtag_tap
*tap
;
396 uint8_t *buffer
= NULL
;
398 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
400 tap
= str9xpec_info
->tap
;
402 if (!str9xpec_info
->isc_enable
)
403 str9xpec_isc_enable(bank
);
405 if (!str9xpec_info
->isc_enable
)
406 return ISC_STATUS_ERROR
;
408 buffer
= calloc(DIV_ROUND_UP(64, 8), 1);
410 LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first
, last
);
412 /* last bank: 0xFF signals a full erase (unlock complete device) */
413 /* last bank: 0xFE signals a option byte erase */
415 for (i
= 0; i
< 64; i
++)
416 buf_set_u32(buffer
, i
, 1, 1);
417 } else if (last
== 0xFE)
418 buf_set_u32(buffer
, 49, 1, 1);
420 for (i
= first
; i
<= last
; i
++)
421 buf_set_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1, 1);
424 LOG_DEBUG("ISC_ERASE");
426 /* execute ISC_ERASE command */
427 str9xpec_set_instr(tap
, ISC_ERASE
, TAP_IRPAUSE
);
430 field
.out_value
= buffer
;
431 field
.in_value
= NULL
;
433 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
434 jtag_execute_queue();
438 /* wait for erase completion */
439 while (!((status
= str9xpec_isc_status(tap
)) & ISC_STATUS_BUSY
))
444 str9xpec_isc_disable(bank
);
449 static int str9xpec_erase(struct flash_bank
*bank
, int first
, int last
)
453 status
= str9xpec_erase_area(bank
, first
, last
);
455 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
456 return ERROR_FLASH_OPERATION_FAILED
;
461 static int str9xpec_lock_device(struct flash_bank
*bank
)
463 struct scan_field field
;
465 struct jtag_tap
*tap
;
466 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
468 str9xpec_info
= bank
->driver_priv
;
469 tap
= str9xpec_info
->tap
;
471 if (!str9xpec_info
->isc_enable
)
472 str9xpec_isc_enable(bank
);
474 if (!str9xpec_info
->isc_enable
)
475 return ISC_STATUS_ERROR
;
477 /* set security address */
478 str9xpec_set_address(bank
, 0x80);
480 /* execute ISC_PROGRAM command */
481 str9xpec_set_instr(tap
, ISC_PROGRAM_SECURITY
, TAP_IDLE
);
483 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
487 field
.out_value
= NULL
;
488 field
.in_value
= &status
;
490 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
491 jtag_execute_queue();
493 } while (!(status
& ISC_STATUS_BUSY
));
495 str9xpec_isc_disable(bank
);
500 static int str9xpec_unlock_device(struct flash_bank
*bank
)
504 status
= str9xpec_erase_area(bank
, 0, 255);
509 static int str9xpec_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
514 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
516 status
= str9xpec_read_config(bank
);
518 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
519 return ERROR_FLASH_OPERATION_FAILED
;
521 LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first
, last
);
523 /* last bank: 0xFF signals a full device protect */
526 status
= str9xpec_lock_device(bank
);
528 /* perform full erase to unlock device */
529 status
= str9xpec_unlock_device(bank
);
532 for (i
= first
; i
<= last
; i
++) {
534 buf_set_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1, 1);
536 buf_set_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1, 0);
539 status
= str9xpec_write_options(bank
);
542 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
543 return ERROR_FLASH_OPERATION_FAILED
;
548 static int str9xpec_set_address(struct flash_bank
*bank
, uint8_t sector
)
550 struct jtag_tap
*tap
;
551 struct scan_field field
;
552 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
554 tap
= str9xpec_info
->tap
;
556 /* set flash controller address */
557 str9xpec_set_instr(tap
, ISC_ADDRESS_SHIFT
, TAP_IRPAUSE
);
560 field
.out_value
= §or
;
561 field
.in_value
= NULL
;
563 jtag_add_dr_scan(tap
, 1, &field
, TAP_IRPAUSE
);
568 static int str9xpec_write(struct flash_bank
*bank
, uint8_t *buffer
,
569 uint32_t offset
, uint32_t count
)
571 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
572 uint32_t dwords_remaining
= (count
/ 8);
573 uint32_t bytes_remaining
= (count
& 0x00000007);
574 uint32_t bytes_written
= 0;
576 uint32_t check_address
= offset
;
577 struct jtag_tap
*tap
;
578 struct scan_field field
;
581 int first_sector
= 0;
584 tap
= str9xpec_info
->tap
;
586 if (!str9xpec_info
->isc_enable
)
587 str9xpec_isc_enable(bank
);
589 if (!str9xpec_info
->isc_enable
)
590 return ERROR_FLASH_OPERATION_FAILED
;
593 LOG_WARNING("offset 0x%" PRIx32
" breaks required 8-byte alignment", offset
);
594 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
597 for (i
= 0; i
< bank
->num_sectors
; i
++) {
598 uint32_t sec_start
= bank
->sectors
[i
].offset
;
599 uint32_t sec_end
= sec_start
+ bank
->sectors
[i
].size
;
601 /* check if destination falls within the current sector */
602 if ((check_address
>= sec_start
) && (check_address
< sec_end
)) {
603 /* check if destination ends in the current sector */
604 if (offset
+ count
< sec_end
)
605 check_address
= offset
+ count
;
607 check_address
= sec_end
;
610 if ((offset
>= sec_start
) && (offset
< sec_end
))
613 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
++) {
627 str9xpec_set_address(bank
, str9xpec_info
->sector_bits
[i
]);
629 dwords_remaining
= dwords_remaining
< (bank
->sectors
[i
].size
/8)
630 ? dwords_remaining
: (bank
->sectors
[i
].size
/8);
632 while (dwords_remaining
> 0) {
633 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
636 field
.out_value
= (buffer
+ bytes_written
);
637 field
.in_value
= NULL
;
639 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
641 /* small delay before polling */
644 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
648 field
.out_value
= NULL
;
649 field
.in_value
= scanbuf
;
651 jtag_add_dr_scan(tap
, 1, &field
, TAP_IRPAUSE
);
652 jtag_execute_queue();
654 status
= buf_get_u32(scanbuf
, 0, 8);
656 } while (!(status
& ISC_STATUS_BUSY
));
658 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
659 return ERROR_FLASH_OPERATION_FAILED
;
661 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
662 return ERROR_FLASH_OPERATION_FAILED; */
669 if (bytes_remaining
) {
670 uint8_t last_dword
[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
672 /* copy the last remaining bytes into the write buffer */
673 memcpy(last_dword
, buffer
+bytes_written
, bytes_remaining
);
675 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
678 field
.out_value
= last_dword
;
679 field
.in_value
= NULL
;
681 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
683 /* small delay before polling */
686 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
690 field
.out_value
= NULL
;
691 field
.in_value
= scanbuf
;
693 jtag_add_dr_scan(tap
, 1, &field
, TAP_IRPAUSE
);
694 jtag_execute_queue();
696 status
= buf_get_u32(scanbuf
, 0, 8);
698 } while (!(status
& ISC_STATUS_BUSY
));
700 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
701 return ERROR_FLASH_OPERATION_FAILED
;
703 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
704 return ERROR_FLASH_OPERATION_FAILED; */
709 str9xpec_isc_disable(bank
);
714 static int str9xpec_probe(struct flash_bank
*bank
)
719 COMMAND_HANDLER(str9xpec_handle_part_id_command
)
721 struct scan_field field
;
722 uint8_t *buffer
= NULL
;
723 struct jtag_tap
*tap
;
725 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
728 return ERROR_COMMAND_SYNTAX_ERROR
;
730 struct flash_bank
*bank
;
731 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
732 if (ERROR_OK
!= retval
)
735 str9xpec_info
= bank
->driver_priv
;
736 tap
= str9xpec_info
->tap
;
738 buffer
= calloc(DIV_ROUND_UP(32, 8), 1);
740 str9xpec_set_instr(tap
, ISC_IDCODE
, TAP_IRPAUSE
);
743 field
.out_value
= NULL
;
744 field
.in_value
= buffer
;
746 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
747 jtag_execute_queue();
749 idcode
= buf_get_u32(buffer
, 0, 32);
751 command_print(CMD_CTX
, "str9xpec part id: 0x%8.8" PRIx32
"", idcode
);
758 static int str9xpec_erase_check(struct flash_bank
*bank
)
760 return str9xpec_blank_check(bank
, 0, bank
->num_sectors
- 1);
763 static int get_str9xpec_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
765 snprintf(buf
, buf_size
, "str9xpec flash driver info");
769 COMMAND_HANDLER(str9xpec_handle_flash_options_read_command
)
772 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
775 return ERROR_COMMAND_SYNTAX_ERROR
;
777 struct flash_bank
*bank
;
778 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
779 if (ERROR_OK
!= retval
)
782 str9xpec_info
= bank
->driver_priv
;
784 status
= str9xpec_read_config(bank
);
786 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
787 return ERROR_FLASH_OPERATION_FAILED
;
790 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1))
791 command_print(CMD_CTX
, "CS Map: bank1");
793 command_print(CMD_CTX
, "CS Map: bank0");
796 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_OTPBIT
, 1))
797 command_print(CMD_CTX
, "OTP Lock: OTP Locked");
799 command_print(CMD_CTX
, "OTP Lock: OTP Unlocked");
802 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1))
803 command_print(CMD_CTX
, "LVD Threshold: 2.7v");
805 command_print(CMD_CTX
, "LVD Threshold: 2.4v");
807 /* LVD reset warning */
808 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1))
809 command_print(CMD_CTX
, "LVD Reset Warning: VDD or VDDQ Inputs");
811 command_print(CMD_CTX
, "LVD Reset Warning: VDD Input Only");
813 /* LVD reset select */
814 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1))
815 command_print(CMD_CTX
, "LVD Reset Selection: VDD or VDDQ Inputs");
817 command_print(CMD_CTX
, "LVD Reset Selection: VDD Input Only");
822 static int str9xpec_write_options(struct flash_bank
*bank
)
824 struct scan_field field
;
826 struct jtag_tap
*tap
;
827 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
829 str9xpec_info
= bank
->driver_priv
;
830 tap
= str9xpec_info
->tap
;
832 /* erase config options first */
833 status
= str9xpec_erase_area(bank
, 0xFE, 0xFE);
835 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
838 if (!str9xpec_info
->isc_enable
)
839 str9xpec_isc_enable(bank
);
841 if (!str9xpec_info
->isc_enable
)
842 return ISC_STATUS_ERROR
;
844 /* according to data 64th bit has to be set */
845 buf_set_u32(str9xpec_info
->options
, 63, 1, 1);
847 /* set option byte address */
848 str9xpec_set_address(bank
, 0x50);
850 /* execute ISC_PROGRAM command */
851 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
854 field
.out_value
= str9xpec_info
->options
;
855 field
.in_value
= NULL
;
857 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
859 /* small delay before polling */
862 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
866 field
.out_value
= NULL
;
867 field
.in_value
= &status
;
869 jtag_add_dr_scan(tap
, 1, &field
, TAP_IRPAUSE
);
870 jtag_execute_queue();
872 } while (!(status
& ISC_STATUS_BUSY
));
874 str9xpec_isc_disable(bank
);
879 COMMAND_HANDLER(str9xpec_handle_flash_options_write_command
)
884 return ERROR_COMMAND_SYNTAX_ERROR
;
886 struct flash_bank
*bank
;
887 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
888 if (ERROR_OK
!= retval
)
891 status
= str9xpec_write_options(bank
);
893 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
894 return ERROR_FLASH_OPERATION_FAILED
;
896 command_print(CMD_CTX
, "str9xpec write options complete.\n"
897 "INFO: a reset or power cycle is required "
898 "for the new settings to take effect.");
903 COMMAND_HANDLER(str9xpec_handle_flash_options_cmap_command
)
905 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
908 return ERROR_COMMAND_SYNTAX_ERROR
;
910 struct flash_bank
*bank
;
911 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
912 if (ERROR_OK
!= retval
)
915 str9xpec_info
= bank
->driver_priv
;
917 if (strcmp(CMD_ARGV
[1], "bank1") == 0)
918 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 1);
920 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 0);
925 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdthd_command
)
927 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
930 return ERROR_COMMAND_SYNTAX_ERROR
;
932 struct flash_bank
*bank
;
933 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
934 if (ERROR_OK
!= retval
)
937 str9xpec_info
= bank
->driver_priv
;
939 if (strcmp(CMD_ARGV
[1], "2.7v") == 0)
940 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 1);
942 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 0);
947 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdsel_command
)
949 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
952 return ERROR_COMMAND_SYNTAX_ERROR
;
954 struct flash_bank
*bank
;
955 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
956 if (ERROR_OK
!= retval
)
959 str9xpec_info
= bank
->driver_priv
;
961 if (strcmp(CMD_ARGV
[1], "vdd_vddq") == 0)
962 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 1);
964 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 0);
969 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdwarn_command
)
971 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
974 return ERROR_COMMAND_SYNTAX_ERROR
;
976 struct flash_bank
*bank
;
977 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
978 if (ERROR_OK
!= retval
)
981 str9xpec_info
= bank
->driver_priv
;
983 if (strcmp(CMD_ARGV
[1], "vdd_vddq") == 0)
984 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 1);
986 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 0);
991 COMMAND_HANDLER(str9xpec_handle_flash_lock_command
)
996 return ERROR_COMMAND_SYNTAX_ERROR
;
998 struct flash_bank
*bank
;
999 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1000 if (ERROR_OK
!= retval
)
1003 status
= str9xpec_lock_device(bank
);
1005 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1006 return ERROR_FLASH_OPERATION_FAILED
;
1011 COMMAND_HANDLER(str9xpec_handle_flash_unlock_command
)
1016 return ERROR_COMMAND_SYNTAX_ERROR
;
1018 struct flash_bank
*bank
;
1019 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1020 if (ERROR_OK
!= retval
)
1023 status
= str9xpec_unlock_device(bank
);
1025 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1026 return ERROR_FLASH_OPERATION_FAILED
;
1028 command_print(CMD_CTX
, "str9xpec unlocked.\n"
1029 "INFO: a reset or power cycle is required "
1030 "for the new settings to take effect.");
1035 COMMAND_HANDLER(str9xpec_handle_flash_enable_turbo_command
)
1037 struct jtag_tap
*tap0
;
1038 struct jtag_tap
*tap1
;
1039 struct jtag_tap
*tap2
;
1040 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
1043 return ERROR_COMMAND_SYNTAX_ERROR
;
1045 struct flash_bank
*bank
;
1046 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1047 if (ERROR_OK
!= retval
)
1050 str9xpec_info
= bank
->driver_priv
;
1052 /* remove arm core from chain - enter turbo mode */
1053 tap0
= str9xpec_info
->tap
;
1055 /* things are *WRONG* */
1056 command_print(CMD_CTX
, "**STR9FLASH** (tap0) invalid chain?");
1059 tap1
= tap0
->next_tap
;
1061 /* things are *WRONG* */
1062 command_print(CMD_CTX
, "**STR9FLASH** (tap1) invalid chain?");
1065 tap2
= tap1
->next_tap
;
1067 /* things are *WRONG* */
1068 command_print(CMD_CTX
, "**STR9FLASH** (tap2) invalid chain?");
1072 /* enable turbo mode - TURBO-PROG-ENABLE */
1073 str9xpec_set_instr(tap2
, 0xD, TAP_IDLE
);
1074 retval
= jtag_execute_queue();
1075 if (retval
!= ERROR_OK
)
1078 /* modify scan chain - str9 core has been removed */
1084 COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command
)
1086 struct jtag_tap
*tap
;
1087 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
1090 return ERROR_COMMAND_SYNTAX_ERROR
;
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
;
1098 tap
= str9xpec_info
->tap
;
1103 /* exit turbo mode via RESET */
1104 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IDLE
);
1106 jtag_execute_queue();
1108 /* restore previous scan chain */
1110 tap
->next_tap
->enabled
= 1;
1115 static const struct command_registration str9xpec_config_command_handlers
[] = {
1117 .name
= "enable_turbo",
1119 .handler
= str9xpec_handle_flash_enable_turbo_command
,
1120 .mode
= COMMAND_EXEC
,
1121 .help
= "enable str9xpec turbo mode",
1124 .name
= "disable_turbo",
1126 .handler
= str9xpec_handle_flash_disable_turbo_command
,
1127 .mode
= COMMAND_EXEC
,
1128 .help
= "disable str9xpec turbo mode",
1131 .name
= "options_cmap",
1132 .usage
= "<bank> <bank0 | bank1>",
1133 .handler
= str9xpec_handle_flash_options_cmap_command
,
1134 .mode
= COMMAND_EXEC
,
1135 .help
= "configure str9xpec boot sector",
1138 .name
= "options_lvdthd",
1139 .usage
= "<bank> <2.4v | 2.7v>",
1140 .handler
= str9xpec_handle_flash_options_lvdthd_command
,
1141 .mode
= COMMAND_EXEC
,
1142 .help
= "configure str9xpec lvd threshold",
1145 .name
= "options_lvdsel",
1146 .usage
= "<bank> <vdd | vdd_vddq>",
1147 .handler
= str9xpec_handle_flash_options_lvdsel_command
,
1148 .mode
= COMMAND_EXEC
,
1149 .help
= "configure str9xpec lvd selection",
1152 .name
= "options_lvdwarn",
1153 .usage
= "<bank> <vdd | vdd_vddq>",
1154 .handler
= str9xpec_handle_flash_options_lvdwarn_command
,
1155 .mode
= COMMAND_EXEC
,
1156 .help
= "configure str9xpec lvd warning",
1159 .name
= "options_read",
1161 .handler
= str9xpec_handle_flash_options_read_command
,
1162 .mode
= COMMAND_EXEC
,
1163 .help
= "read str9xpec options",
1166 .name
= "options_write",
1168 .handler
= str9xpec_handle_flash_options_write_command
,
1169 .mode
= COMMAND_EXEC
,
1170 .help
= "write str9xpec options",
1175 .handler
= str9xpec_handle_flash_lock_command
,
1176 .mode
= COMMAND_EXEC
,
1177 .help
= "lock str9xpec device",
1182 .handler
= str9xpec_handle_flash_unlock_command
,
1183 .mode
= COMMAND_EXEC
,
1184 .help
= "unlock str9xpec device",
1188 .handler
= str9xpec_handle_part_id_command
,
1189 .mode
= COMMAND_EXEC
,
1190 .help
= "print part id of str9xpec flash bank <num>",
1192 COMMAND_REGISTRATION_DONE
1195 static const struct command_registration str9xpec_command_handlers
[] = {
1198 .mode
= COMMAND_ANY
,
1199 .help
= "str9xpec flash command group",
1201 .chain
= str9xpec_config_command_handlers
,
1203 COMMAND_REGISTRATION_DONE
1206 struct flash_driver str9xpec_flash
= {
1208 .commands
= str9xpec_command_handlers
,
1209 .flash_bank_command
= str9xpec_flash_bank_command
,
1210 .erase
= str9xpec_erase
,
1211 .protect
= str9xpec_protect
,
1212 .write
= str9xpec_write
,
1213 .read
= default_flash_read
,
1214 .probe
= str9xpec_probe
,
1215 .auto_probe
= str9xpec_probe
,
1216 .erase_check
= str9xpec_erase_check
,
1217 .protect_check
= str9xpec_protect_check
,
1218 .info
= get_str9xpec_info
,