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 str9xpec_info
->tap
= bank
->target
->tap
;
310 str9xpec_info
->isc_enable
= 0;
312 str9xpec_build_block_list(bank
);
314 /* clear option byte register */
315 buf_set_u32(str9xpec_info
->options
, 0, 64, 0);
320 static int str9xpec_blank_check(struct flash_bank
*bank
, int first
, int last
)
322 struct scan_field field
;
324 struct jtag_tap
*tap
;
326 uint8_t *buffer
= NULL
;
328 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
330 tap
= str9xpec_info
->tap
;
332 if (!str9xpec_info
->isc_enable
) {
333 str9xpec_isc_enable(bank
);
336 if (!str9xpec_info
->isc_enable
) {
337 return ERROR_FLASH_OPERATION_FAILED
;
340 buffer
= calloc(DIV_ROUND_UP(64, 8), 1);
342 LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first
, last
);
344 for (i
= first
; i
<= last
; i
++) {
345 buf_set_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1, 1);
348 /* execute ISC_BLANK_CHECK command */
349 str9xpec_set_instr(tap
, ISC_BLANK_CHECK
, TAP_IRPAUSE
);
352 field
.out_value
= buffer
;
353 field
.in_value
= NULL
;
355 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
356 jtag_add_sleep(40000);
358 /* read blank check result */
360 field
.out_value
= NULL
;
361 field
.in_value
= buffer
;
363 jtag_add_dr_scan(tap
, 1, &field
, TAP_IRPAUSE
);
364 jtag_execute_queue();
366 status
= str9xpec_isc_status(tap
);
368 for (i
= first
; i
<= last
; i
++)
370 if (buf_get_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1))
371 bank
->sectors
[i
].is_erased
= 0;
373 bank
->sectors
[i
].is_erased
= 1;
378 str9xpec_isc_disable(bank
);
380 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
381 return ERROR_FLASH_OPERATION_FAILED
;
385 static int str9xpec_protect_check(struct flash_bank
*bank
)
390 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
392 status
= str9xpec_read_config(bank
);
394 for (i
= 0; i
< bank
->num_sectors
; i
++)
396 if (buf_get_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1))
397 bank
->sectors
[i
].is_protected
= 1;
399 bank
->sectors
[i
].is_protected
= 0;
402 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
403 return ERROR_FLASH_OPERATION_FAILED
;
407 static int str9xpec_erase_area(struct flash_bank
*bank
, int first
, int last
)
409 struct scan_field field
;
411 struct jtag_tap
*tap
;
413 uint8_t *buffer
= NULL
;
415 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
417 tap
= str9xpec_info
->tap
;
419 if (!str9xpec_info
->isc_enable
) {
420 str9xpec_isc_enable(bank
);
423 if (!str9xpec_info
->isc_enable
) {
424 return ISC_STATUS_ERROR
;
427 buffer
= calloc(DIV_ROUND_UP(64, 8), 1);
429 LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first
, last
);
431 /* last bank: 0xFF signals a full erase (unlock complete device) */
432 /* last bank: 0xFE signals a option byte erase */
435 for (i
= 0; i
< 64; i
++) {
436 buf_set_u32(buffer
, i
, 1, 1);
439 else if (last
== 0xFE)
441 buf_set_u32(buffer
, 49, 1, 1);
445 for (i
= first
; i
<= last
; i
++) {
446 buf_set_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1, 1);
450 LOG_DEBUG("ISC_ERASE");
452 /* execute ISC_ERASE command */
453 str9xpec_set_instr(tap
, ISC_ERASE
, TAP_IRPAUSE
);
456 field
.out_value
= buffer
;
457 field
.in_value
= NULL
;
459 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
460 jtag_execute_queue();
464 /* wait for erase completion */
465 while (!((status
= str9xpec_isc_status(tap
)) & ISC_STATUS_BUSY
)) {
471 str9xpec_isc_disable(bank
);
476 static int str9xpec_erase(struct flash_bank
*bank
, int first
, int last
)
480 status
= str9xpec_erase_area(bank
, first
, last
);
482 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
483 return ERROR_FLASH_OPERATION_FAILED
;
488 static int str9xpec_lock_device(struct flash_bank
*bank
)
490 struct scan_field field
;
492 struct jtag_tap
*tap
;
493 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
495 str9xpec_info
= bank
->driver_priv
;
496 tap
= str9xpec_info
->tap
;
498 if (!str9xpec_info
->isc_enable
) {
499 str9xpec_isc_enable(bank
);
502 if (!str9xpec_info
->isc_enable
) {
503 return ISC_STATUS_ERROR
;
506 /* set security address */
507 str9xpec_set_address(bank
, 0x80);
509 /* execute ISC_PROGRAM command */
510 str9xpec_set_instr(tap
, ISC_PROGRAM_SECURITY
, TAP_IDLE
);
512 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
516 field
.out_value
= NULL
;
517 field
.in_value
= &status
;
519 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
520 jtag_execute_queue();
522 } while (!(status
& ISC_STATUS_BUSY
));
524 str9xpec_isc_disable(bank
);
529 static int str9xpec_unlock_device(struct flash_bank
*bank
)
533 status
= str9xpec_erase_area(bank
, 0, 255);
538 static int str9xpec_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
543 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
545 status
= str9xpec_read_config(bank
);
547 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
548 return ERROR_FLASH_OPERATION_FAILED
;
550 LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first
, last
);
552 /* last bank: 0xFF signals a full device protect */
557 status
= str9xpec_lock_device(bank
);
561 /* perform full erase to unlock device */
562 status
= str9xpec_unlock_device(bank
);
567 for (i
= first
; i
<= last
; i
++)
570 buf_set_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1, 1);
572 buf_set_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1, 0);
575 status
= str9xpec_write_options(bank
);
578 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
579 return ERROR_FLASH_OPERATION_FAILED
;
584 static int str9xpec_set_address(struct flash_bank
*bank
, uint8_t sector
)
586 struct jtag_tap
*tap
;
587 struct scan_field field
;
588 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
590 tap
= str9xpec_info
->tap
;
592 /* set flash controller address */
593 str9xpec_set_instr(tap
, ISC_ADDRESS_SHIFT
, TAP_IRPAUSE
);
596 field
.out_value
= §or
;
597 field
.in_value
= NULL
;
599 jtag_add_dr_scan(tap
, 1, &field
, TAP_IRPAUSE
);
604 static int str9xpec_write(struct flash_bank
*bank
, uint8_t *buffer
,
605 uint32_t offset
, uint32_t count
)
607 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
608 uint32_t dwords_remaining
= (count
/ 8);
609 uint32_t bytes_remaining
= (count
& 0x00000007);
610 uint32_t bytes_written
= 0;
612 uint32_t check_address
= offset
;
613 struct jtag_tap
*tap
;
614 struct scan_field field
;
617 int first_sector
= 0;
620 tap
= str9xpec_info
->tap
;
622 if (!str9xpec_info
->isc_enable
) {
623 str9xpec_isc_enable(bank
);
626 if (!str9xpec_info
->isc_enable
) {
627 return ERROR_FLASH_OPERATION_FAILED
;
632 LOG_WARNING("offset 0x%" PRIx32
" breaks required 8-byte alignment", offset
);
633 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
636 for (i
= 0; i
< bank
->num_sectors
; i
++)
638 uint32_t sec_start
= bank
->sectors
[i
].offset
;
639 uint32_t sec_end
= sec_start
+ bank
->sectors
[i
].size
;
641 /* check if destination falls within the current sector */
642 if ((check_address
>= sec_start
) && (check_address
< sec_end
))
644 /* check if destination ends in the current sector */
645 if (offset
+ count
< sec_end
)
646 check_address
= offset
+ count
;
648 check_address
= sec_end
;
651 if ((offset
>= sec_start
) && (offset
< sec_end
)) {
655 if ((offset
+ count
>= sec_start
) && (offset
+ count
< sec_end
)) {
660 if (check_address
!= offset
+ count
)
661 return ERROR_FLASH_DST_OUT_OF_BANK
;
663 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector
, last_sector
);
665 scanbuf
= calloc(DIV_ROUND_UP(64, 8), 1);
667 LOG_DEBUG("ISC_PROGRAM");
669 for (i
= first_sector
; i
<= last_sector
; i
++)
671 str9xpec_set_address(bank
, str9xpec_info
->sector_bits
[i
]);
673 dwords_remaining
= dwords_remaining
< (bank
->sectors
[i
].size
/8)
674 ? dwords_remaining
: (bank
->sectors
[i
].size
/8);
676 while (dwords_remaining
> 0)
678 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
681 field
.out_value
= (buffer
+ bytes_written
);
682 field
.in_value
= NULL
;
684 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
686 /* small delay before polling */
689 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
693 field
.out_value
= NULL
;
694 field
.in_value
= scanbuf
;
696 jtag_add_dr_scan(tap
, 1, &field
, TAP_IRPAUSE
);
697 jtag_execute_queue();
699 status
= buf_get_u32(scanbuf
, 0, 8);
701 } while (!(status
& ISC_STATUS_BUSY
));
703 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
704 return ERROR_FLASH_OPERATION_FAILED
;
706 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
707 return ERROR_FLASH_OPERATION_FAILED; */
716 uint8_t last_dword
[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
719 while (bytes_remaining
> 0)
721 last_dword
[i
++] = *(buffer
+ bytes_written
);
726 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
729 field
.out_value
= last_dword
;
730 field
.in_value
= NULL
;
732 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
734 /* small delay before polling */
737 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
741 field
.out_value
= NULL
;
742 field
.in_value
= scanbuf
;
744 jtag_add_dr_scan(tap
, 1, &field
, TAP_IRPAUSE
);
745 jtag_execute_queue();
747 status
= buf_get_u32(scanbuf
, 0, 8);
749 } while (!(status
& ISC_STATUS_BUSY
));
751 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
752 return ERROR_FLASH_OPERATION_FAILED
;
754 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
755 return ERROR_FLASH_OPERATION_FAILED; */
760 str9xpec_isc_disable(bank
);
765 static int str9xpec_probe(struct flash_bank
*bank
)
770 COMMAND_HANDLER(str9xpec_handle_part_id_command
)
772 struct scan_field field
;
773 uint8_t *buffer
= NULL
;
774 struct jtag_tap
*tap
;
776 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
779 return ERROR_COMMAND_SYNTAX_ERROR
;
781 struct flash_bank
*bank
;
782 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
783 if (ERROR_OK
!= retval
)
786 str9xpec_info
= bank
->driver_priv
;
787 tap
= str9xpec_info
->tap
;
789 buffer
= calloc(DIV_ROUND_UP(32, 8), 1);
791 str9xpec_set_instr(tap
, ISC_IDCODE
, TAP_IRPAUSE
);
794 field
.out_value
= NULL
;
795 field
.in_value
= buffer
;
797 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
798 jtag_execute_queue();
800 idcode
= buf_get_u32(buffer
, 0, 32);
802 command_print(CMD_CTX
, "str9xpec part id: 0x%8.8" PRIx32
"", idcode
);
809 static int str9xpec_erase_check(struct flash_bank
*bank
)
811 return str9xpec_blank_check(bank
, 0, bank
->num_sectors
- 1);
814 static int get_str9xpec_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
816 snprintf(buf
, buf_size
, "str9xpec flash driver info");
820 COMMAND_HANDLER(str9xpec_handle_flash_options_read_command
)
823 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
827 command_print(CMD_CTX
, "str9xpec options_read <bank>");
831 struct flash_bank
*bank
;
832 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
833 if (ERROR_OK
!= retval
)
836 str9xpec_info
= bank
->driver_priv
;
838 status
= str9xpec_read_config(bank
);
840 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
841 return ERROR_FLASH_OPERATION_FAILED
;
844 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1))
845 command_print(CMD_CTX
, "CS Map: bank1");
847 command_print(CMD_CTX
, "CS Map: bank0");
850 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_OTPBIT
, 1))
851 command_print(CMD_CTX
, "OTP Lock: OTP Locked");
853 command_print(CMD_CTX
, "OTP Lock: OTP Unlocked");
856 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1))
857 command_print(CMD_CTX
, "LVD Threshold: 2.7v");
859 command_print(CMD_CTX
, "LVD Threshold: 2.4v");
861 /* LVD reset warning */
862 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1))
863 command_print(CMD_CTX
, "LVD Reset Warning: VDD or VDDQ Inputs");
865 command_print(CMD_CTX
, "LVD Reset Warning: VDD Input Only");
867 /* LVD reset select */
868 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1))
869 command_print(CMD_CTX
, "LVD Reset Selection: VDD or VDDQ Inputs");
871 command_print(CMD_CTX
, "LVD Reset Selection: VDD Input Only");
876 static int str9xpec_write_options(struct flash_bank
*bank
)
878 struct scan_field field
;
880 struct jtag_tap
*tap
;
881 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
883 str9xpec_info
= bank
->driver_priv
;
884 tap
= str9xpec_info
->tap
;
886 /* erase config options first */
887 status
= str9xpec_erase_area(bank
, 0xFE, 0xFE);
889 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
892 if (!str9xpec_info
->isc_enable
) {
893 str9xpec_isc_enable(bank
);
896 if (!str9xpec_info
->isc_enable
) {
897 return ISC_STATUS_ERROR
;
900 /* according to data 64th bit has to be set */
901 buf_set_u32(str9xpec_info
->options
, 63, 1, 1);
903 /* set option byte address */
904 str9xpec_set_address(bank
, 0x50);
906 /* execute ISC_PROGRAM command */
907 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
910 field
.out_value
= str9xpec_info
->options
;
911 field
.in_value
= NULL
;
913 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
915 /* small delay before polling */
918 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
922 field
.out_value
= NULL
;
923 field
.in_value
= &status
;
925 jtag_add_dr_scan(tap
, 1, &field
, TAP_IRPAUSE
);
926 jtag_execute_queue();
928 } while (!(status
& ISC_STATUS_BUSY
));
930 str9xpec_isc_disable(bank
);
935 COMMAND_HANDLER(str9xpec_handle_flash_options_write_command
)
941 command_print(CMD_CTX
, "str9xpec options_write <bank>");
945 struct flash_bank
*bank
;
946 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
947 if (ERROR_OK
!= retval
)
950 status
= str9xpec_write_options(bank
);
952 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
953 return ERROR_FLASH_OPERATION_FAILED
;
955 command_print(CMD_CTX
, "str9xpec write options complete.\n"
956 "INFO: a reset or power cycle is required "
957 "for the new settings to take effect.");
962 COMMAND_HANDLER(str9xpec_handle_flash_options_cmap_command
)
964 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
968 command_print(CMD_CTX
, "str9xpec options_cmap <bank> <bank0 | bank1>");
972 struct flash_bank
*bank
;
973 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
974 if (ERROR_OK
!= retval
)
977 str9xpec_info
= bank
->driver_priv
;
979 if (strcmp(CMD_ARGV
[1], "bank1") == 0)
981 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 1);
985 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 0);
991 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdthd_command
)
993 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
997 command_print(CMD_CTX
, "str9xpec options_lvdthd <bank> <2.4v | 2.7v>");
1001 struct flash_bank
*bank
;
1002 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1003 if (ERROR_OK
!= retval
)
1006 str9xpec_info
= bank
->driver_priv
;
1008 if (strcmp(CMD_ARGV
[1], "2.7v") == 0)
1010 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 1);
1014 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 0);
1020 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdsel_command
)
1022 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
1026 command_print(CMD_CTX
, "str9xpec options_lvdsel <bank> <vdd | vdd_vddq>");
1030 struct flash_bank
*bank
;
1031 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1032 if (ERROR_OK
!= retval
)
1035 str9xpec_info
= bank
->driver_priv
;
1037 if (strcmp(CMD_ARGV
[1], "vdd_vddq") == 0)
1039 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 1);
1043 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 0);
1049 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdwarn_command
)
1051 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
1055 command_print(CMD_CTX
, "str9xpec options_lvdwarn <bank> <vdd | vdd_vddq>");
1059 struct flash_bank
*bank
;
1060 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1061 if (ERROR_OK
!= retval
)
1064 str9xpec_info
= bank
->driver_priv
;
1066 if (strcmp(CMD_ARGV
[1], "vdd_vddq") == 0)
1068 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 1);
1072 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 0);
1078 COMMAND_HANDLER(str9xpec_handle_flash_lock_command
)
1084 command_print(CMD_CTX
, "str9xpec lock <bank>");
1088 struct flash_bank
*bank
;
1089 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1090 if (ERROR_OK
!= retval
)
1093 status
= str9xpec_lock_device(bank
);
1095 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1096 return ERROR_FLASH_OPERATION_FAILED
;
1101 COMMAND_HANDLER(str9xpec_handle_flash_unlock_command
)
1107 command_print(CMD_CTX
, "str9xpec unlock <bank>");
1111 struct flash_bank
*bank
;
1112 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1113 if (ERROR_OK
!= retval
)
1116 status
= str9xpec_unlock_device(bank
);
1118 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1119 return ERROR_FLASH_OPERATION_FAILED
;
1121 command_print(CMD_CTX
, "str9xpec unlocked.\n"
1122 "INFO: a reset or power cycle is required "
1123 "for the new settings to take effect.");
1128 COMMAND_HANDLER(str9xpec_handle_flash_enable_turbo_command
)
1130 struct jtag_tap
*tap0
;
1131 struct jtag_tap
*tap1
;
1132 struct jtag_tap
*tap2
;
1133 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
1137 command_print(CMD_CTX
, "str9xpec enable_turbo <bank>");
1141 struct flash_bank
*bank
;
1142 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1143 if (ERROR_OK
!= retval
)
1146 str9xpec_info
= bank
->driver_priv
;
1148 tap0
= str9xpec_info
->tap
;
1150 /* remove arm core from chain - enter turbo mode */
1151 tap1
= tap0
->next_tap
;
1154 /* things are *WRONG* */
1155 command_print(CMD_CTX
,"**STR9FLASH** (tap1) invalid chain?");
1158 tap2
= tap1
->next_tap
;
1161 /* things are *WRONG* */
1162 command_print(CMD_CTX
,"**STR9FLASH** (tap2) invalid chain?");
1166 /* enable turbo mode - TURBO-PROG-ENABLE */
1167 str9xpec_set_instr(tap2
, 0xD, TAP_IDLE
);
1168 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
1171 /* modify scan chain - str9 core has been removed */
1177 COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command
)
1179 struct jtag_tap
*tap
;
1180 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
1184 command_print(CMD_CTX
, "str9xpec disable_turbo <bank>");
1188 struct flash_bank
*bank
;
1189 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1190 if (ERROR_OK
!= retval
)
1193 str9xpec_info
= bank
->driver_priv
;
1194 tap
= str9xpec_info
->tap
;
1199 /* exit turbo mode via RESET */
1200 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IDLE
);
1202 jtag_execute_queue();
1204 /* restore previous scan chain */
1205 if (tap
->next_tap
) {
1206 tap
->next_tap
->enabled
= 1;
1212 static const struct command_registration str9xpec_config_command_handlers
[] = {
1214 .name
= "enable_turbo",
1215 .handler
= str9xpec_handle_flash_enable_turbo_command
,
1216 .mode
= COMMAND_EXEC
,
1217 .help
= "enable str9xpec turbo mode",
1220 .name
= "disable_turbo",
1221 .handler
= str9xpec_handle_flash_disable_turbo_command
,
1222 .mode
= COMMAND_EXEC
,
1223 .help
= "disable str9xpec turbo mode",
1226 .name
= "options_cmap",
1227 .handler
= str9xpec_handle_flash_options_cmap_command
,
1228 .mode
= COMMAND_EXEC
,
1229 .help
= "configure str9xpec boot sector",
1232 .name
= "options_lvdthd",
1233 .handler
= str9xpec_handle_flash_options_lvdthd_command
,
1234 .mode
= COMMAND_EXEC
,
1235 .help
= "configure str9xpec lvd threshold",
1238 .name
= "options_lvdsel",
1239 .handler
= str9xpec_handle_flash_options_lvdsel_command
,
1240 .mode
= COMMAND_EXEC
,
1241 .help
= "configure str9xpec lvd selection",
1244 .name
= "options_lvdwarn",
1245 .handler
= str9xpec_handle_flash_options_lvdwarn_command
,
1246 .mode
= COMMAND_EXEC
,
1247 .help
= "configure str9xpec lvd warning",
1250 .name
= "options_read",
1251 .handler
= str9xpec_handle_flash_options_read_command
,
1252 .mode
= COMMAND_EXEC
,
1253 .help
= "read str9xpec options",
1256 .name
= "options_write",
1257 .handler
= str9xpec_handle_flash_options_write_command
,
1258 .mode
= COMMAND_EXEC
,
1259 .help
= "write str9xpec options",
1263 .handler
= str9xpec_handle_flash_lock_command
,
1264 .mode
= COMMAND_EXEC
,
1265 .help
= "lock str9xpec device",
1269 .handler
= str9xpec_handle_flash_unlock_command
,
1270 .mode
= COMMAND_EXEC
,
1271 .help
= "unlock str9xpec device",
1275 .handler
= str9xpec_handle_part_id_command
,
1276 .mode
= COMMAND_EXEC
,
1277 .help
= "print part id of str9xpec flash bank <num>",
1279 COMMAND_REGISTRATION_DONE
1282 static const struct command_registration str9xpec_command_handlers
[] = {
1285 .mode
= COMMAND_ANY
,
1286 .help
= "str9xpec flash command group",
1287 .chain
= str9xpec_config_command_handlers
,
1289 COMMAND_REGISTRATION_DONE
1292 struct flash_driver str9xpec_flash
= {
1294 .commands
= str9xpec_command_handlers
,
1295 .flash_bank_command
= str9xpec_flash_bank_command
,
1296 .erase
= str9xpec_erase
,
1297 .protect
= str9xpec_protect
,
1298 .write
= str9xpec_write
,
1299 .read
= default_flash_read
,
1300 .probe
= str9xpec_probe
,
1301 .auto_probe
= str9xpec_probe
,
1302 .erase_check
= str9xpec_erase_check
,
1303 .protect_check
= str9xpec_protect_check
,
1304 .info
= get_str9xpec_info
,