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 "arm7_9_common.h"
31 static int str9xpec_register_commands(struct command_context_s
*cmd_ctx
);
32 static int str9xpec_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
);
33 static int str9xpec_erase(struct flash_bank_s
*bank
, int first
, int last
);
34 static int str9xpec_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
);
35 static int str9xpec_write(struct flash_bank_s
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
);
36 static int str9xpec_probe(struct flash_bank_s
*bank
);
37 static int str9xpec_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
38 static int str9xpec_protect_check(struct flash_bank_s
*bank
);
39 static int str9xpec_erase_check(struct flash_bank_s
*bank
);
40 static int str9xpec_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
);
42 static int str9xpec_erase_area(struct flash_bank_s
*bank
, int first
, int last
);
43 static int str9xpec_set_address(struct flash_bank_s
*bank
, uint8_t sector
);
44 static int str9xpec_write_options(struct flash_bank_s
*bank
);
46 static int str9xpec_handle_flash_options_cmap_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
47 static int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
48 static int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
49 static int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
50 static int str9xpec_handle_flash_options_read_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
51 static int str9xpec_handle_flash_options_write_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
52 static int str9xpec_handle_flash_lock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
53 static int str9xpec_handle_flash_unlock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
54 static int str9xpec_handle_flash_enable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
55 static int str9xpec_handle_flash_disable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
57 flash_driver_t str9xpec_flash
=
60 .register_commands
= str9xpec_register_commands
,
61 .flash_bank_command
= str9xpec_flash_bank_command
,
62 .erase
= str9xpec_erase
,
63 .protect
= str9xpec_protect
,
64 .write
= str9xpec_write
,
65 .probe
= str9xpec_probe
,
66 .auto_probe
= str9xpec_probe
,
67 .erase_check
= str9xpec_erase_check
,
68 .protect_check
= str9xpec_protect_check
,
72 static int str9xpec_register_commands(struct command_context_s
*cmd_ctx
)
74 command_t
*str9xpec_cmd
= register_command(cmd_ctx
, NULL
, "str9xpec", NULL
, COMMAND_ANY
, "str9xpec flash specific commands");
76 register_command(cmd_ctx
, str9xpec_cmd
, "enable_turbo", str9xpec_handle_flash_enable_turbo_command
, COMMAND_EXEC
,
77 "enable str9xpec turbo mode");
78 register_command(cmd_ctx
, str9xpec_cmd
, "disable_turbo", str9xpec_handle_flash_disable_turbo_command
, COMMAND_EXEC
,
79 "disable str9xpec turbo mode");
80 register_command(cmd_ctx
, str9xpec_cmd
, "options_cmap", str9xpec_handle_flash_options_cmap_command
, COMMAND_EXEC
,
81 "configure str9xpec boot sector");
82 register_command(cmd_ctx
, str9xpec_cmd
, "options_lvdthd", str9xpec_handle_flash_options_lvdthd_command
, COMMAND_EXEC
,
83 "configure str9xpec lvd threshold");
84 register_command(cmd_ctx
, str9xpec_cmd
, "options_lvdsel", str9xpec_handle_flash_options_lvdsel_command
, COMMAND_EXEC
,
85 "configure str9xpec lvd selection");
86 register_command(cmd_ctx
, str9xpec_cmd
, "options_lvdwarn", str9xpec_handle_flash_options_lvdwarn_command
, COMMAND_EXEC
,
87 "configure str9xpec lvd warning");
88 register_command(cmd_ctx
, str9xpec_cmd
, "options_read", str9xpec_handle_flash_options_read_command
, COMMAND_EXEC
,
89 "read str9xpec options");
90 register_command(cmd_ctx
, str9xpec_cmd
, "options_write", str9xpec_handle_flash_options_write_command
, COMMAND_EXEC
,
91 "write str9xpec options");
92 register_command(cmd_ctx
, str9xpec_cmd
, "lock", str9xpec_handle_flash_lock_command
, COMMAND_EXEC
,
93 "lock str9xpec device");
94 register_command(cmd_ctx
, str9xpec_cmd
, "unlock", str9xpec_handle_flash_unlock_command
, COMMAND_EXEC
,
95 "unlock str9xpec device");
96 register_command(cmd_ctx
, str9xpec_cmd
, "part_id", str9xpec_handle_part_id_command
, COMMAND_EXEC
,
97 "print part id of str9xpec flash bank <num>");
102 int str9xpec_set_instr(jtag_tap_t
*tap
, uint32_t new_instr
, tap_state_t end_state
)
105 return ERROR_TARGET_INVALID
;
108 if (buf_get_u32(tap
->cur_instr
, 0, tap
->ir_length
) != new_instr
)
113 field
.num_bits
= tap
->ir_length
;
114 field
.out_value
= calloc(CEIL(field
.num_bits
, 8), 1);
115 buf_set_u32(field
.out_value
, 0, field
.num_bits
, new_instr
);
116 field
.in_value
= NULL
;
118 jtag_add_ir_scan(1, &field
, end_state
);
120 free(field
.out_value
);
126 static uint8_t str9xpec_isc_status(jtag_tap_t
*tap
)
131 if (str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
) != ERROR_OK
)
132 return ISC_STATUS_ERROR
;
136 field
.out_value
= NULL
;
137 field
.in_value
= &status
;
140 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
141 jtag_execute_queue();
143 LOG_DEBUG("status: 0x%2.2x", status
);
145 if (status
& ISC_STATUS_SECURITY
)
146 LOG_INFO("Device Security Bit Set");
151 static int str9xpec_isc_enable(struct flash_bank_s
*bank
)
155 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
157 tap
= str9xpec_info
->tap
;
159 if (str9xpec_info
->isc_enable
)
163 if (str9xpec_set_instr(tap
, ISC_ENABLE
, TAP_IDLE
) != ERROR_OK
)
164 return ERROR_TARGET_INVALID
;
166 /* check ISC status */
167 status
= str9xpec_isc_status(tap
);
168 if (status
& ISC_STATUS_MODE
)
170 /* we have entered isc mode */
171 str9xpec_info
->isc_enable
= 1;
172 LOG_DEBUG("ISC_MODE Enabled");
178 static int str9xpec_isc_disable(struct flash_bank_s
*bank
)
182 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
184 tap
= str9xpec_info
->tap
;
186 if (!str9xpec_info
->isc_enable
)
189 if (str9xpec_set_instr(tap
, ISC_DISABLE
, TAP_IDLE
) != ERROR_OK
)
190 return ERROR_TARGET_INVALID
;
192 /* delay to handle aborts */
195 /* check ISC status */
196 status
= str9xpec_isc_status(tap
);
197 if (!(status
& ISC_STATUS_MODE
))
199 /* we have left isc mode */
200 str9xpec_info
->isc_enable
= 0;
201 LOG_DEBUG("ISC_MODE Disabled");
207 static int str9xpec_read_config(struct flash_bank_s
*bank
)
213 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
215 tap
= str9xpec_info
->tap
;
217 LOG_DEBUG("ISC_CONFIGURATION");
219 /* execute ISC_CONFIGURATION command */
220 str9xpec_set_instr(tap
, ISC_CONFIGURATION
, TAP_IRPAUSE
);
224 field
.out_value
= NULL
;
225 field
.in_value
= str9xpec_info
->options
;
228 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
229 jtag_execute_queue();
231 status
= str9xpec_isc_status(tap
);
236 static int str9xpec_build_block_list(struct flash_bank_s
*bank
)
238 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
242 int b0_sectors
= 0, b1_sectors
= 0;
244 int b1_size
= 0x2000;
268 LOG_ERROR("BUG: unknown bank->size encountered");
272 num_sectors
= b0_sectors
+ b1_sectors
;
274 bank
->num_sectors
= num_sectors
;
275 bank
->sectors
= malloc(sizeof(flash_sector_t
) * num_sectors
);
276 str9xpec_info
->sector_bits
= malloc(sizeof(uint32_t) * num_sectors
);
280 for (i
= 0; i
< b0_sectors
; i
++)
282 bank
->sectors
[num_sectors
].offset
= offset
;
283 bank
->sectors
[num_sectors
].size
= 0x10000;
284 offset
+= bank
->sectors
[i
].size
;
285 bank
->sectors
[num_sectors
].is_erased
= -1;
286 bank
->sectors
[num_sectors
].is_protected
= 1;
287 str9xpec_info
->sector_bits
[num_sectors
++] = i
;
290 for (i
= 0; i
< b1_sectors
; i
++)
292 bank
->sectors
[num_sectors
].offset
= offset
;
293 bank
->sectors
[num_sectors
].size
= b1_size
;
294 offset
+= bank
->sectors
[i
].size
;
295 bank
->sectors
[num_sectors
].is_erased
= -1;
296 bank
->sectors
[num_sectors
].is_protected
= 1;
297 str9xpec_info
->sector_bits
[num_sectors
++] = i
+ 32;
303 /* flash bank str9x <base> <size> 0 0 <target#>
305 static int str9xpec_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
307 str9xpec_flash_controller_t
*str9xpec_info
;
308 armv4_5_common_t
*armv4_5
= NULL
;
309 arm7_9_common_t
*arm7_9
= NULL
;
310 arm_jtag_t
*jtag_info
= NULL
;
314 LOG_WARNING("incomplete flash_bank str9x configuration");
315 return ERROR_FLASH_BANK_INVALID
;
318 str9xpec_info
= malloc(sizeof(str9xpec_flash_controller_t
));
319 bank
->driver_priv
= str9xpec_info
;
321 /* REVISIT verify that the jtag position of flash controller is
322 * right after *THIS* core, which must be a STR9xx core ...
324 armv4_5
= bank
->target
->arch_info
;
325 arm7_9
= armv4_5
->arch_info
;
326 jtag_info
= &arm7_9
->jtag_info
;
328 str9xpec_info
->tap
= bank
->target
->tap
;
329 str9xpec_info
->isc_enable
= 0;
331 str9xpec_build_block_list(bank
);
333 /* clear option byte register */
334 buf_set_u32(str9xpec_info
->options
, 0, 64, 0);
339 static int str9xpec_blank_check(struct flash_bank_s
*bank
, int first
, int last
)
345 uint8_t *buffer
= NULL
;
347 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
349 tap
= str9xpec_info
->tap
;
351 if (!str9xpec_info
->isc_enable
) {
352 str9xpec_isc_enable(bank
);
355 if (!str9xpec_info
->isc_enable
) {
356 return ERROR_FLASH_OPERATION_FAILED
;
359 buffer
= calloc(CEIL(64, 8), 1);
361 LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first
, last
);
363 for (i
= first
; i
<= last
; i
++) {
364 buf_set_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1, 1);
367 /* execute ISC_BLANK_CHECK command */
368 str9xpec_set_instr(tap
, ISC_BLANK_CHECK
, TAP_IRPAUSE
);
372 field
.out_value
= buffer
;
373 field
.in_value
= NULL
;
375 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
376 jtag_add_sleep(40000);
378 /* read blank check result */
381 field
.out_value
= NULL
;
382 field
.in_value
= buffer
;
384 jtag_add_dr_scan(1, &field
, TAP_IRPAUSE
);
385 jtag_execute_queue();
387 status
= str9xpec_isc_status(tap
);
389 for (i
= first
; i
<= last
; i
++)
391 if (buf_get_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1))
392 bank
->sectors
[i
].is_erased
= 0;
394 bank
->sectors
[i
].is_erased
= 1;
399 str9xpec_isc_disable(bank
);
401 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
402 return ERROR_FLASH_OPERATION_FAILED
;
406 static int str9xpec_protect_check(struct flash_bank_s
*bank
)
411 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
413 status
= str9xpec_read_config(bank
);
415 for (i
= 0; i
< bank
->num_sectors
; i
++)
417 if (buf_get_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1))
418 bank
->sectors
[i
].is_protected
= 1;
420 bank
->sectors
[i
].is_protected
= 0;
423 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
424 return ERROR_FLASH_OPERATION_FAILED
;
428 static int str9xpec_erase_area(struct flash_bank_s
*bank
, int first
, int last
)
434 uint8_t *buffer
= NULL
;
436 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
438 tap
= str9xpec_info
->tap
;
440 if (!str9xpec_info
->isc_enable
) {
441 str9xpec_isc_enable(bank
);
444 if (!str9xpec_info
->isc_enable
) {
445 return ISC_STATUS_ERROR
;
448 buffer
= calloc(CEIL(64, 8), 1);
450 LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first
, last
);
452 /* last bank: 0xFF signals a full erase (unlock complete device) */
453 /* last bank: 0xFE signals a option byte erase */
456 for (i
= 0; i
< 64; i
++) {
457 buf_set_u32(buffer
, i
, 1, 1);
460 else if (last
== 0xFE)
462 buf_set_u32(buffer
, 49, 1, 1);
466 for (i
= first
; i
<= last
; i
++) {
467 buf_set_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1, 1);
471 LOG_DEBUG("ISC_ERASE");
473 /* execute ISC_ERASE command */
474 str9xpec_set_instr(tap
, ISC_ERASE
, TAP_IRPAUSE
);
478 field
.out_value
= buffer
;
479 field
.in_value
= NULL
;
481 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
482 jtag_execute_queue();
486 /* wait for erase completion */
487 while (!((status
= str9xpec_isc_status(tap
)) & ISC_STATUS_BUSY
)) {
493 str9xpec_isc_disable(bank
);
498 static int str9xpec_erase(struct flash_bank_s
*bank
, int first
, int last
)
502 status
= str9xpec_erase_area(bank
, first
, last
);
504 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
505 return ERROR_FLASH_OPERATION_FAILED
;
510 static int str9xpec_lock_device(struct flash_bank_s
*bank
)
515 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
517 str9xpec_info
= bank
->driver_priv
;
518 tap
= str9xpec_info
->tap
;
520 if (!str9xpec_info
->isc_enable
) {
521 str9xpec_isc_enable(bank
);
524 if (!str9xpec_info
->isc_enable
) {
525 return ISC_STATUS_ERROR
;
528 /* set security address */
529 str9xpec_set_address(bank
, 0x80);
531 /* execute ISC_PROGRAM command */
532 str9xpec_set_instr(tap
, ISC_PROGRAM_SECURITY
, TAP_IDLE
);
534 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
539 field
.out_value
= NULL
;
540 field
.in_value
= &status
;
542 jtag_add_dr_scan(1, &field
, jtag_get_end_state());
543 jtag_execute_queue();
545 } while (!(status
& ISC_STATUS_BUSY
));
547 str9xpec_isc_disable(bank
);
552 static int str9xpec_unlock_device(struct flash_bank_s
*bank
)
556 status
= str9xpec_erase_area(bank
, 0, 255);
561 static int str9xpec_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
566 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
568 status
= str9xpec_read_config(bank
);
570 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
571 return ERROR_FLASH_OPERATION_FAILED
;
573 LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first
, last
);
575 /* last bank: 0xFF signals a full device protect */
580 status
= str9xpec_lock_device(bank
);
584 /* perform full erase to unlock device */
585 status
= str9xpec_unlock_device(bank
);
590 for (i
= first
; i
<= last
; i
++)
593 buf_set_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1, 1);
595 buf_set_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1, 0);
598 status
= str9xpec_write_options(bank
);
601 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
602 return ERROR_FLASH_OPERATION_FAILED
;
607 static int str9xpec_set_address(struct flash_bank_s
*bank
, uint8_t sector
)
611 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
613 tap
= str9xpec_info
->tap
;
615 /* set flash controller address */
616 str9xpec_set_instr(tap
, ISC_ADDRESS_SHIFT
, TAP_IRPAUSE
);
620 field
.out_value
= §or
;
621 field
.in_value
= NULL
;
623 jtag_add_dr_scan(1, &field
, jtag_get_end_state());
628 static int str9xpec_write(struct flash_bank_s
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
630 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
631 uint32_t dwords_remaining
= (count
/ 8);
632 uint32_t bytes_remaining
= (count
& 0x00000007);
633 uint32_t bytes_written
= 0;
635 uint32_t check_address
= offset
;
640 int first_sector
= 0;
643 tap
= str9xpec_info
->tap
;
645 if (!str9xpec_info
->isc_enable
) {
646 str9xpec_isc_enable(bank
);
649 if (!str9xpec_info
->isc_enable
) {
650 return ERROR_FLASH_OPERATION_FAILED
;
655 LOG_WARNING("offset 0x%" PRIx32
" breaks required 8-byte alignment", offset
);
656 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
659 for (i
= 0; i
< bank
->num_sectors
; i
++)
661 uint32_t sec_start
= bank
->sectors
[i
].offset
;
662 uint32_t sec_end
= sec_start
+ bank
->sectors
[i
].size
;
664 /* check if destination falls within the current sector */
665 if ((check_address
>= sec_start
) && (check_address
< sec_end
))
667 /* check if destination ends in the current sector */
668 if (offset
+ count
< sec_end
)
669 check_address
= offset
+ count
;
671 check_address
= sec_end
;
674 if ((offset
>= sec_start
) && (offset
< sec_end
)) {
678 if ((offset
+ count
>= sec_start
) && (offset
+ count
< sec_end
)) {
683 if (check_address
!= offset
+ count
)
684 return ERROR_FLASH_DST_OUT_OF_BANK
;
686 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector
, last_sector
);
688 scanbuf
= calloc(CEIL(64, 8), 1);
690 LOG_DEBUG("ISC_PROGRAM");
692 for (i
= first_sector
; i
<= last_sector
; i
++)
694 str9xpec_set_address(bank
, str9xpec_info
->sector_bits
[i
]);
696 dwords_remaining
= dwords_remaining
< (bank
->sectors
[i
].size
/8) ? dwords_remaining
: (bank
->sectors
[i
].size
/8);
698 while (dwords_remaining
> 0)
700 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
704 field
.out_value
= (buffer
+ bytes_written
);
705 field
.in_value
= NULL
;
707 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
709 /* small delay before polling */
712 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
717 field
.out_value
= NULL
;
718 field
.in_value
= scanbuf
;
720 jtag_add_dr_scan(1, &field
, jtag_get_end_state());
721 jtag_execute_queue();
723 status
= buf_get_u32(scanbuf
, 0, 8);
725 } while (!(status
& ISC_STATUS_BUSY
));
727 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
728 return ERROR_FLASH_OPERATION_FAILED
;
730 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
731 return ERROR_FLASH_OPERATION_FAILED; */
740 uint8_t last_dword
[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
743 while (bytes_remaining
> 0)
745 last_dword
[i
++] = *(buffer
+ bytes_written
);
750 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
754 field
.out_value
= last_dword
;
755 field
.in_value
= NULL
;
757 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
759 /* small delay before polling */
762 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
767 field
.out_value
= NULL
;
768 field
.in_value
= scanbuf
;
770 jtag_add_dr_scan(1, &field
, jtag_get_end_state());
771 jtag_execute_queue();
773 status
= buf_get_u32(scanbuf
, 0, 8);
775 } while (!(status
& ISC_STATUS_BUSY
));
777 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
778 return ERROR_FLASH_OPERATION_FAILED
;
780 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
781 return ERROR_FLASH_OPERATION_FAILED; */
786 str9xpec_isc_disable(bank
);
791 static int str9xpec_probe(struct flash_bank_s
*bank
)
796 static int str9xpec_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
799 uint8_t *buffer
= NULL
;
802 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
805 return ERROR_COMMAND_SYNTAX_ERROR
;
808 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
809 if (ERROR_OK
!= retval
)
812 str9xpec_info
= bank
->driver_priv
;
813 tap
= str9xpec_info
->tap
;
815 buffer
= calloc(CEIL(32, 8), 1);
817 str9xpec_set_instr(tap
, ISC_IDCODE
, TAP_IRPAUSE
);
821 field
.out_value
= NULL
;
822 field
.in_value
= buffer
;
824 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
825 jtag_execute_queue();
827 idcode
= buf_get_u32(buffer
, 0, 32);
829 command_print(cmd_ctx
, "str9xpec part id: 0x%8.8" PRIx32
"", idcode
);
836 static int str9xpec_erase_check(struct flash_bank_s
*bank
)
838 return str9xpec_blank_check(bank
, 0, bank
->num_sectors
- 1);
841 static int str9xpec_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
843 snprintf(buf
, buf_size
, "str9xpec flash driver info");
847 static int str9xpec_handle_flash_options_read_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
850 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
854 command_print(cmd_ctx
, "str9xpec options_read <bank>");
859 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
860 if (ERROR_OK
!= retval
)
863 str9xpec_info
= bank
->driver_priv
;
865 status
= str9xpec_read_config(bank
);
867 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
868 return ERROR_FLASH_OPERATION_FAILED
;
871 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1))
872 command_print(cmd_ctx
, "CS Map: bank1");
874 command_print(cmd_ctx
, "CS Map: bank0");
877 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_OTPBIT
, 1))
878 command_print(cmd_ctx
, "OTP Lock: OTP Locked");
880 command_print(cmd_ctx
, "OTP Lock: OTP Unlocked");
883 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1))
884 command_print(cmd_ctx
, "LVD Threshold: 2.7v");
886 command_print(cmd_ctx
, "LVD Threshold: 2.4v");
888 /* LVD reset warning */
889 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1))
890 command_print(cmd_ctx
, "LVD Reset Warning: VDD or VDDQ Inputs");
892 command_print(cmd_ctx
, "LVD Reset Warning: VDD Input Only");
894 /* LVD reset select */
895 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1))
896 command_print(cmd_ctx
, "LVD Reset Selection: VDD or VDDQ Inputs");
898 command_print(cmd_ctx
, "LVD Reset Selection: VDD Input Only");
903 static int str9xpec_write_options(struct flash_bank_s
*bank
)
908 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
910 str9xpec_info
= bank
->driver_priv
;
911 tap
= str9xpec_info
->tap
;
913 /* erase config options first */
914 status
= str9xpec_erase_area(bank
, 0xFE, 0xFE);
916 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
919 if (!str9xpec_info
->isc_enable
) {
920 str9xpec_isc_enable(bank
);
923 if (!str9xpec_info
->isc_enable
) {
924 return ISC_STATUS_ERROR
;
927 /* according to data 64th bit has to be set */
928 buf_set_u32(str9xpec_info
->options
, 63, 1, 1);
930 /* set option byte address */
931 str9xpec_set_address(bank
, 0x50);
933 /* execute ISC_PROGRAM command */
934 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
938 field
.out_value
= str9xpec_info
->options
;
939 field
.in_value
= NULL
;
941 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
943 /* small delay before polling */
946 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
951 field
.out_value
= NULL
;
952 field
.in_value
= &status
;
954 jtag_add_dr_scan(1, &field
, jtag_get_end_state());
955 jtag_execute_queue();
957 } while (!(status
& ISC_STATUS_BUSY
));
959 str9xpec_isc_disable(bank
);
964 static int str9xpec_handle_flash_options_write_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
970 command_print(cmd_ctx
, "str9xpec options_write <bank>");
975 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
976 if (ERROR_OK
!= retval
)
979 status
= str9xpec_write_options(bank
);
981 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
982 return ERROR_FLASH_OPERATION_FAILED
;
987 static int str9xpec_handle_flash_options_cmap_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
989 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
993 command_print(cmd_ctx
, "str9xpec options_cmap <bank> <bank0 | bank1>");
998 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
999 if (ERROR_OK
!= retval
)
1002 str9xpec_info
= bank
->driver_priv
;
1004 if (strcmp(args
[1], "bank1") == 0)
1006 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 1);
1010 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 0);
1016 static int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1018 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1022 command_print(cmd_ctx
, "str9xpec options_lvdthd <bank> <2.4v | 2.7v>");
1027 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
1028 if (ERROR_OK
!= retval
)
1031 str9xpec_info
= bank
->driver_priv
;
1033 if (strcmp(args
[1], "2.7v") == 0)
1035 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 1);
1039 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 0);
1045 int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1047 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1051 command_print(cmd_ctx
, "str9xpec options_lvdsel <bank> <vdd | vdd_vddq>");
1056 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
1057 if (ERROR_OK
!= retval
)
1060 str9xpec_info
= bank
->driver_priv
;
1062 if (strcmp(args
[1], "vdd_vddq") == 0)
1064 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 1);
1068 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 0);
1074 static int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1076 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1080 command_print(cmd_ctx
, "str9xpec options_lvdwarn <bank> <vdd | vdd_vddq>");
1085 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
1086 if (ERROR_OK
!= retval
)
1089 str9xpec_info
= bank
->driver_priv
;
1091 if (strcmp(args
[1], "vdd_vddq") == 0)
1093 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 1);
1097 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 0);
1103 static int str9xpec_handle_flash_lock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1109 command_print(cmd_ctx
, "str9xpec lock <bank>");
1114 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
1115 if (ERROR_OK
!= retval
)
1118 status
= str9xpec_lock_device(bank
);
1120 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1121 return ERROR_FLASH_OPERATION_FAILED
;
1126 static int str9xpec_handle_flash_unlock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1132 command_print(cmd_ctx
, "str9xpec unlock <bank>");
1137 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
1138 if (ERROR_OK
!= retval
)
1141 status
= str9xpec_unlock_device(bank
);
1143 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1144 return ERROR_FLASH_OPERATION_FAILED
;
1149 static int str9xpec_handle_flash_enable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1154 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1158 command_print(cmd_ctx
, "str9xpec enable_turbo <bank>");
1163 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
1164 if (ERROR_OK
!= retval
)
1167 str9xpec_info
= bank
->driver_priv
;
1169 tap0
= str9xpec_info
->tap
;
1171 /* remove arm core from chain - enter turbo mode */
1172 tap1
= tap0
->next_tap
;
1175 /* things are *WRONG* */
1176 command_print(cmd_ctx
,"**STR9FLASH** (tap1) invalid chain?");
1179 tap2
= tap1
->next_tap
;
1182 /* things are *WRONG* */
1183 command_print(cmd_ctx
,"**STR9FLASH** (tap2) invalid chain?");
1187 /* enable turbo mode - TURBO-PROG-ENABLE */
1188 str9xpec_set_instr(tap2
, 0xD, TAP_IDLE
);
1189 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
1192 /* modify scan chain - str9 core has been removed */
1198 static int str9xpec_handle_flash_disable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1201 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1205 command_print(cmd_ctx
, "str9xpec disable_turbo <bank>");
1210 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
1211 if (ERROR_OK
!= retval
)
1214 str9xpec_info
= bank
->driver_priv
;
1215 tap
= str9xpec_info
->tap
;
1220 /* exit turbo mode via RESET */
1221 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IDLE
);
1223 jtag_execute_queue();
1225 /* restore previous scan chain */
1226 if (tap
->next_tap
) {
1227 tap
->next_tap
->enabled
= 1;