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 return ERROR_COMMAND_SYNTAX_ERROR
;
298 str9xpec_info
= malloc(sizeof(struct str9xpec_flash_controller
));
299 bank
->driver_priv
= str9xpec_info
;
301 /* REVISIT verify that the jtag position of flash controller is
302 * right after *THIS* core, which must be a STR9xx core ...
304 armv4_5
= bank
->target
->arch_info
;
305 arm7_9
= armv4_5
->arch_info
;
306 jtag_info
= &arm7_9
->jtag_info
;
308 /* The core is the next tap after the flash controller in the chain */
309 str9xpec_info
->tap
= jtag_tap_by_position(jtag_info
->tap
->abs_chain_position
- 1);
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};
718 /* copy the last remaining bytes into the write buffer */
719 memcpy(last_dword
, buffer
+bytes_written
, bytes_remaining
);
721 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
724 field
.out_value
= last_dword
;
725 field
.in_value
= NULL
;
727 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
729 /* small delay before polling */
732 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
736 field
.out_value
= NULL
;
737 field
.in_value
= scanbuf
;
739 jtag_add_dr_scan(tap
, 1, &field
, TAP_IRPAUSE
);
740 jtag_execute_queue();
742 status
= buf_get_u32(scanbuf
, 0, 8);
744 } while (!(status
& ISC_STATUS_BUSY
));
746 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
747 return ERROR_FLASH_OPERATION_FAILED
;
749 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
750 return ERROR_FLASH_OPERATION_FAILED; */
755 str9xpec_isc_disable(bank
);
760 static int str9xpec_probe(struct flash_bank
*bank
)
765 COMMAND_HANDLER(str9xpec_handle_part_id_command
)
767 struct scan_field field
;
768 uint8_t *buffer
= NULL
;
769 struct jtag_tap
*tap
;
771 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
774 return ERROR_COMMAND_SYNTAX_ERROR
;
776 struct flash_bank
*bank
;
777 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
778 if (ERROR_OK
!= retval
)
781 str9xpec_info
= bank
->driver_priv
;
782 tap
= str9xpec_info
->tap
;
784 buffer
= calloc(DIV_ROUND_UP(32, 8), 1);
786 str9xpec_set_instr(tap
, ISC_IDCODE
, TAP_IRPAUSE
);
789 field
.out_value
= NULL
;
790 field
.in_value
= buffer
;
792 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
793 jtag_execute_queue();
795 idcode
= buf_get_u32(buffer
, 0, 32);
797 command_print(CMD_CTX
, "str9xpec part id: 0x%8.8" PRIx32
"", idcode
);
804 static int str9xpec_erase_check(struct flash_bank
*bank
)
806 return str9xpec_blank_check(bank
, 0, bank
->num_sectors
- 1);
809 static int get_str9xpec_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
811 snprintf(buf
, buf_size
, "str9xpec flash driver info");
815 COMMAND_HANDLER(str9xpec_handle_flash_options_read_command
)
818 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
822 return ERROR_COMMAND_SYNTAX_ERROR
;
825 struct flash_bank
*bank
;
826 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
827 if (ERROR_OK
!= retval
)
830 str9xpec_info
= bank
->driver_priv
;
832 status
= str9xpec_read_config(bank
);
834 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
835 return ERROR_FLASH_OPERATION_FAILED
;
838 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1))
839 command_print(CMD_CTX
, "CS Map: bank1");
841 command_print(CMD_CTX
, "CS Map: bank0");
844 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_OTPBIT
, 1))
845 command_print(CMD_CTX
, "OTP Lock: OTP Locked");
847 command_print(CMD_CTX
, "OTP Lock: OTP Unlocked");
850 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1))
851 command_print(CMD_CTX
, "LVD Threshold: 2.7v");
853 command_print(CMD_CTX
, "LVD Threshold: 2.4v");
855 /* LVD reset warning */
856 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1))
857 command_print(CMD_CTX
, "LVD Reset Warning: VDD or VDDQ Inputs");
859 command_print(CMD_CTX
, "LVD Reset Warning: VDD Input Only");
861 /* LVD reset select */
862 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1))
863 command_print(CMD_CTX
, "LVD Reset Selection: VDD or VDDQ Inputs");
865 command_print(CMD_CTX
, "LVD Reset Selection: VDD Input Only");
870 static int str9xpec_write_options(struct flash_bank
*bank
)
872 struct scan_field field
;
874 struct jtag_tap
*tap
;
875 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
877 str9xpec_info
= bank
->driver_priv
;
878 tap
= str9xpec_info
->tap
;
880 /* erase config options first */
881 status
= str9xpec_erase_area(bank
, 0xFE, 0xFE);
883 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
886 if (!str9xpec_info
->isc_enable
) {
887 str9xpec_isc_enable(bank
);
890 if (!str9xpec_info
->isc_enable
) {
891 return ISC_STATUS_ERROR
;
894 /* according to data 64th bit has to be set */
895 buf_set_u32(str9xpec_info
->options
, 63, 1, 1);
897 /* set option byte address */
898 str9xpec_set_address(bank
, 0x50);
900 /* execute ISC_PROGRAM command */
901 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
904 field
.out_value
= str9xpec_info
->options
;
905 field
.in_value
= NULL
;
907 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
909 /* small delay before polling */
912 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
916 field
.out_value
= NULL
;
917 field
.in_value
= &status
;
919 jtag_add_dr_scan(tap
, 1, &field
, TAP_IRPAUSE
);
920 jtag_execute_queue();
922 } while (!(status
& ISC_STATUS_BUSY
));
924 str9xpec_isc_disable(bank
);
929 COMMAND_HANDLER(str9xpec_handle_flash_options_write_command
)
935 return ERROR_COMMAND_SYNTAX_ERROR
;
938 struct flash_bank
*bank
;
939 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
940 if (ERROR_OK
!= retval
)
943 status
= str9xpec_write_options(bank
);
945 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
946 return ERROR_FLASH_OPERATION_FAILED
;
948 command_print(CMD_CTX
, "str9xpec write options complete.\n"
949 "INFO: a reset or power cycle is required "
950 "for the new settings to take effect.");
955 COMMAND_HANDLER(str9xpec_handle_flash_options_cmap_command
)
957 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
961 return ERROR_COMMAND_SYNTAX_ERROR
;
964 struct flash_bank
*bank
;
965 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
966 if (ERROR_OK
!= retval
)
969 str9xpec_info
= bank
->driver_priv
;
971 if (strcmp(CMD_ARGV
[1], "bank1") == 0)
973 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 1);
977 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 0);
983 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdthd_command
)
985 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
989 return ERROR_COMMAND_SYNTAX_ERROR
;
992 struct flash_bank
*bank
;
993 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
994 if (ERROR_OK
!= retval
)
997 str9xpec_info
= bank
->driver_priv
;
999 if (strcmp(CMD_ARGV
[1], "2.7v") == 0)
1001 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 1);
1005 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 0);
1011 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdsel_command
)
1013 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
1017 return ERROR_COMMAND_SYNTAX_ERROR
;
1020 struct flash_bank
*bank
;
1021 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1022 if (ERROR_OK
!= retval
)
1025 str9xpec_info
= bank
->driver_priv
;
1027 if (strcmp(CMD_ARGV
[1], "vdd_vddq") == 0)
1029 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 1);
1033 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 0);
1039 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdwarn_command
)
1041 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
1045 return ERROR_COMMAND_SYNTAX_ERROR
;
1048 struct flash_bank
*bank
;
1049 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1050 if (ERROR_OK
!= retval
)
1053 str9xpec_info
= bank
->driver_priv
;
1055 if (strcmp(CMD_ARGV
[1], "vdd_vddq") == 0)
1057 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 1);
1061 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 0);
1067 COMMAND_HANDLER(str9xpec_handle_flash_lock_command
)
1073 return ERROR_COMMAND_SYNTAX_ERROR
;
1076 struct flash_bank
*bank
;
1077 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1078 if (ERROR_OK
!= retval
)
1081 status
= str9xpec_lock_device(bank
);
1083 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1084 return ERROR_FLASH_OPERATION_FAILED
;
1089 COMMAND_HANDLER(str9xpec_handle_flash_unlock_command
)
1095 return ERROR_COMMAND_SYNTAX_ERROR
;
1098 struct flash_bank
*bank
;
1099 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1100 if (ERROR_OK
!= retval
)
1103 status
= str9xpec_unlock_device(bank
);
1105 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1106 return ERROR_FLASH_OPERATION_FAILED
;
1108 command_print(CMD_CTX
, "str9xpec unlocked.\n"
1109 "INFO: a reset or power cycle is required "
1110 "for the new settings to take effect.");
1115 COMMAND_HANDLER(str9xpec_handle_flash_enable_turbo_command
)
1117 struct jtag_tap
*tap0
;
1118 struct jtag_tap
*tap1
;
1119 struct jtag_tap
*tap2
;
1120 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
1124 return ERROR_COMMAND_SYNTAX_ERROR
;
1127 struct flash_bank
*bank
;
1128 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1129 if (ERROR_OK
!= retval
)
1132 str9xpec_info
= bank
->driver_priv
;
1134 tap0
= str9xpec_info
->tap
;
1136 /* remove arm core from chain - enter turbo mode */
1137 tap1
= tap0
->next_tap
;
1140 /* things are *WRONG* */
1141 command_print(CMD_CTX
,"**STR9FLASH** (tap1) invalid chain?");
1144 tap2
= tap1
->next_tap
;
1147 /* things are *WRONG* */
1148 command_print(CMD_CTX
,"**STR9FLASH** (tap2) invalid chain?");
1152 /* enable turbo mode - TURBO-PROG-ENABLE */
1153 str9xpec_set_instr(tap2
, 0xD, TAP_IDLE
);
1154 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
1157 /* modify scan chain - str9 core has been removed */
1163 COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command
)
1165 struct jtag_tap
*tap
;
1166 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
1170 return ERROR_COMMAND_SYNTAX_ERROR
;
1173 struct flash_bank
*bank
;
1174 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1175 if (ERROR_OK
!= retval
)
1178 str9xpec_info
= bank
->driver_priv
;
1179 tap
= str9xpec_info
->tap
;
1184 /* exit turbo mode via RESET */
1185 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IDLE
);
1187 jtag_execute_queue();
1189 /* restore previous scan chain */
1190 if (tap
->next_tap
) {
1191 tap
->next_tap
->enabled
= 1;
1197 static const struct command_registration str9xpec_config_command_handlers
[] = {
1199 .name
= "enable_turbo",
1201 .handler
= str9xpec_handle_flash_enable_turbo_command
,
1202 .mode
= COMMAND_EXEC
,
1203 .help
= "enable str9xpec turbo mode",
1206 .name
= "disable_turbo",
1208 .handler
= str9xpec_handle_flash_disable_turbo_command
,
1209 .mode
= COMMAND_EXEC
,
1210 .help
= "disable str9xpec turbo mode",
1213 .name
= "options_cmap",
1214 .usage
= "<bank> <bank0 | bank1>",
1215 .handler
= str9xpec_handle_flash_options_cmap_command
,
1216 .mode
= COMMAND_EXEC
,
1217 .help
= "configure str9xpec boot sector",
1220 .name
= "options_lvdthd",
1221 .usage
= "<bank> <2.4v | 2.7v>",
1222 .handler
= str9xpec_handle_flash_options_lvdthd_command
,
1223 .mode
= COMMAND_EXEC
,
1224 .help
= "configure str9xpec lvd threshold",
1227 .name
= "options_lvdsel",
1228 .usage
= "<bank> <vdd | vdd_vddq>",
1229 .handler
= str9xpec_handle_flash_options_lvdsel_command
,
1230 .mode
= COMMAND_EXEC
,
1231 .help
= "configure str9xpec lvd selection",
1234 .name
= "options_lvdwarn",
1235 .usage
= "<bank> <vdd | vdd_vddq>",
1236 .handler
= str9xpec_handle_flash_options_lvdwarn_command
,
1237 .mode
= COMMAND_EXEC
,
1238 .help
= "configure str9xpec lvd warning",
1241 .name
= "options_read",
1243 .handler
= str9xpec_handle_flash_options_read_command
,
1244 .mode
= COMMAND_EXEC
,
1245 .help
= "read str9xpec options",
1248 .name
= "options_write",
1250 .handler
= str9xpec_handle_flash_options_write_command
,
1251 .mode
= COMMAND_EXEC
,
1252 .help
= "write str9xpec options",
1257 .handler
= str9xpec_handle_flash_lock_command
,
1258 .mode
= COMMAND_EXEC
,
1259 .help
= "lock str9xpec device",
1264 .handler
= str9xpec_handle_flash_unlock_command
,
1265 .mode
= COMMAND_EXEC
,
1266 .help
= "unlock str9xpec device",
1270 .handler
= str9xpec_handle_part_id_command
,
1271 .mode
= COMMAND_EXEC
,
1272 .help
= "print part id of str9xpec flash bank <num>",
1274 COMMAND_REGISTRATION_DONE
1277 static const struct command_registration str9xpec_command_handlers
[] = {
1280 .mode
= COMMAND_ANY
,
1281 .help
= "str9xpec flash command group",
1282 .chain
= str9xpec_config_command_handlers
,
1284 COMMAND_REGISTRATION_DONE
1287 struct flash_driver str9xpec_flash
= {
1289 .commands
= str9xpec_command_handlers
,
1290 .flash_bank_command
= str9xpec_flash_bank_command
,
1291 .erase
= str9xpec_erase
,
1292 .protect
= str9xpec_protect
,
1293 .write
= str9xpec_write
,
1294 .read
= default_flash_read
,
1295 .probe
= str9xpec_probe
,
1296 .auto_probe
= str9xpec_probe
,
1297 .erase_check
= str9xpec_erase_check
,
1298 .protect_check
= str9xpec_protect_check
,
1299 .info
= get_str9xpec_info
,