1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
24 #include "replacements.h"
31 #include "arm7_9_common.h"
33 #include "binarybuffer.h"
40 int str9xpec_register_commands(struct command_context_s
*cmd_ctx
);
41 int str9xpec_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
);
42 int str9xpec_erase(struct flash_bank_s
*bank
, int first
, int last
);
43 int str9xpec_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
);
44 int str9xpec_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
);
45 int str9xpec_probe(struct flash_bank_s
*bank
);
46 int str9xpec_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
47 int str9xpec_protect_check(struct flash_bank_s
*bank
);
48 int str9xpec_erase_check(struct flash_bank_s
*bank
);
49 int str9xpec_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
);
51 int str9xpec_erase_area(struct flash_bank_s
*bank
, int first
, int last
);
52 int str9xpec_set_address(struct flash_bank_s
*bank
, u8 sector
);
53 int str9xpec_write_options(struct flash_bank_s
*bank
);
55 int str9xpec_handle_flash_options_cmap_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
56 int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
57 int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
58 int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
59 int str9xpec_handle_flash_options_read_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
60 int str9xpec_handle_flash_options_write_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
61 int str9xpec_handle_flash_lock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
62 int str9xpec_handle_flash_unlock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
63 int str9xpec_handle_flash_enable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
64 int str9xpec_handle_flash_disable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
66 flash_driver_t str9xpec_flash
=
69 .register_commands
= str9xpec_register_commands
,
70 .flash_bank_command
= str9xpec_flash_bank_command
,
71 .erase
= str9xpec_erase
,
72 .protect
= str9xpec_protect
,
73 .write
= str9xpec_write
,
74 .probe
= str9xpec_probe
,
75 .auto_probe
= str9xpec_probe
,
76 .erase_check
= str9xpec_erase_check
,
77 .protect_check
= str9xpec_protect_check
,
81 int str9xpec_register_commands(struct command_context_s
*cmd_ctx
)
83 command_t
*str9xpec_cmd
= register_command(cmd_ctx
, NULL
, "str9xpec", NULL
, COMMAND_ANY
, "str9xpec flash specific commands");
85 register_command(cmd_ctx
, str9xpec_cmd
, "enable_turbo", str9xpec_handle_flash_enable_turbo_command
, COMMAND_EXEC
,
86 "enable str9xpec turbo mode");
87 register_command(cmd_ctx
, str9xpec_cmd
, "disable_turbo", str9xpec_handle_flash_disable_turbo_command
, COMMAND_EXEC
,
88 "disable str9xpec turbo mode");
89 register_command(cmd_ctx
, str9xpec_cmd
, "options_cmap", str9xpec_handle_flash_options_cmap_command
, COMMAND_EXEC
,
90 "configure str9xpec boot sector");
91 register_command(cmd_ctx
, str9xpec_cmd
, "options_lvdthd", str9xpec_handle_flash_options_lvdthd_command
, COMMAND_EXEC
,
92 "configure str9xpec lvd threshold");
93 register_command(cmd_ctx
, str9xpec_cmd
, "options_lvdsel", str9xpec_handle_flash_options_lvdsel_command
, COMMAND_EXEC
,
94 "configure str9xpec lvd selection");
95 register_command(cmd_ctx
, str9xpec_cmd
, "options_lvdwarn", str9xpec_handle_flash_options_lvdwarn_command
, COMMAND_EXEC
,
96 "configure str9xpec lvd warning");
97 register_command(cmd_ctx
, str9xpec_cmd
, "options_read", str9xpec_handle_flash_options_read_command
, COMMAND_EXEC
,
98 "read str9xpec options");
99 register_command(cmd_ctx
, str9xpec_cmd
, "options_write", str9xpec_handle_flash_options_write_command
, COMMAND_EXEC
,
100 "write str9xpec options");
101 register_command(cmd_ctx
, str9xpec_cmd
, "lock", str9xpec_handle_flash_lock_command
, COMMAND_EXEC
,
102 "lock str9xpec device");
103 register_command(cmd_ctx
, str9xpec_cmd
, "unlock", str9xpec_handle_flash_unlock_command
, COMMAND_EXEC
,
104 "unlock str9xpec device");
105 register_command(cmd_ctx
, str9xpec_cmd
, "part_id", str9xpec_handle_part_id_command
, COMMAND_EXEC
,
106 "print part id of str9xpec flash bank <num>");
111 int str9xpec_set_instr(int chain_pos
, u32 new_instr
, enum tap_state end_state
)
113 jtag_device_t
*device
= jtag_get_device(chain_pos
);
117 LOG_DEBUG("Invalid Target");
118 return ERROR_TARGET_INVALID
;
121 if (buf_get_u32(device
->cur_instr
, 0, device
->ir_length
) != new_instr
)
125 field
.device
= chain_pos
;
126 field
.num_bits
= device
->ir_length
;
127 field
.out_value
= calloc(CEIL(field
.num_bits
, 8), 1);
128 buf_set_u32(field
.out_value
, 0, field
.num_bits
, new_instr
);
129 field
.out_mask
= NULL
;
130 field
.in_value
= NULL
;
131 field
.in_check_value
= NULL
;
132 field
.in_check_mask
= NULL
;
133 field
.in_handler
= NULL
;
134 field
.in_handler_priv
= NULL
;
136 jtag_add_ir_scan(1, &field
, end_state
);
138 free(field
.out_value
);
144 u8
str9xpec_isc_status(int chain_pos
)
149 if (str9xpec_set_instr(chain_pos
, ISC_NOOP
, TAP_PI
) != ERROR_OK
)
150 return ISC_STATUS_ERROR
;
152 field
.device
= chain_pos
;
154 field
.out_value
= NULL
;
155 field
.out_mask
= NULL
;
156 field
.in_value
= &status
;
157 field
.in_check_value
= NULL
;
158 field
.in_check_mask
= NULL
;
159 field
.in_handler
= NULL
;
160 field
.in_handler_priv
= NULL
;
162 jtag_add_dr_scan(1, &field
, TAP_RTI
);
163 jtag_execute_queue();
165 LOG_DEBUG("status: 0x%2.2x", status
);
167 if (status
& ISC_STATUS_SECURITY
)
168 LOG_INFO("Device Security Bit Set");
173 int str9xpec_isc_enable(struct flash_bank_s
*bank
)
177 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
179 chain_pos
= str9xpec_info
->chain_pos
;
181 if (str9xpec_info
->isc_enable
)
185 if (str9xpec_set_instr(chain_pos
, ISC_ENABLE
, TAP_RTI
) != ERROR_OK
)
186 return ERROR_TARGET_INVALID
;
188 /* check ISC status */
189 status
= str9xpec_isc_status(chain_pos
);
190 if (status
& ISC_STATUS_MODE
)
192 /* we have entered isc mode */
193 str9xpec_info
->isc_enable
= 1;
194 LOG_DEBUG("ISC_MODE Enabled");
200 int str9xpec_isc_disable(struct flash_bank_s
*bank
)
204 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
206 chain_pos
= str9xpec_info
->chain_pos
;
208 if (!str9xpec_info
->isc_enable
)
211 if (str9xpec_set_instr(chain_pos
, ISC_DISABLE
, TAP_RTI
) != ERROR_OK
)
212 return ERROR_TARGET_INVALID
;
214 /* delay to handle aborts */
217 /* check ISC status */
218 status
= str9xpec_isc_status(chain_pos
);
219 if (!(status
& ISC_STATUS_MODE
))
221 /* we have left isc mode */
222 str9xpec_info
->isc_enable
= 0;
223 LOG_DEBUG("ISC_MODE Disabled");
229 int str9xpec_read_config(struct flash_bank_s
*bank
)
235 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
237 chain_pos
= str9xpec_info
->chain_pos
;
239 LOG_DEBUG("ISC_CONFIGURATION");
241 /* execute ISC_CONFIGURATION command */
242 str9xpec_set_instr(chain_pos
, ISC_CONFIGURATION
, TAP_PI
);
244 field
.device
= chain_pos
;
246 field
.out_value
= NULL
;
247 field
.out_mask
= NULL
;
248 field
.in_value
= str9xpec_info
->options
;
249 field
.in_check_value
= NULL
;
250 field
.in_check_mask
= NULL
;
251 field
.in_handler
= NULL
;
252 field
.in_handler_priv
= NULL
;
254 jtag_add_dr_scan(1, &field
, TAP_RTI
);
255 jtag_execute_queue();
257 status
= str9xpec_isc_status(chain_pos
);
262 int str9xpec_build_block_list(struct flash_bank_s
*bank
)
264 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
268 int b0_sectors
= 0, b1_sectors
= 0;
270 int b1_size
= 0x2000;
294 LOG_ERROR("BUG: unknown bank->size encountered");
298 num_sectors
= b0_sectors
+ b1_sectors
;
300 bank
->num_sectors
= num_sectors
;
301 bank
->sectors
= malloc(sizeof(flash_sector_t
) * num_sectors
);
302 str9xpec_info
->sector_bits
= malloc(sizeof(u32
) * num_sectors
);
306 for (i
= 0; i
< b0_sectors
; i
++)
308 bank
->sectors
[num_sectors
].offset
= offset
;
309 bank
->sectors
[num_sectors
].size
= 0x10000;
310 offset
+= bank
->sectors
[i
].size
;
311 bank
->sectors
[num_sectors
].is_erased
= -1;
312 bank
->sectors
[num_sectors
].is_protected
= 1;
313 str9xpec_info
->sector_bits
[num_sectors
++] = i
;
316 for (i
= 0; i
< b1_sectors
; i
++)
318 bank
->sectors
[num_sectors
].offset
= offset
;
319 bank
->sectors
[num_sectors
].size
= b1_size
;
320 offset
+= bank
->sectors
[i
].size
;
321 bank
->sectors
[num_sectors
].is_erased
= -1;
322 bank
->sectors
[num_sectors
].is_protected
= 1;
323 str9xpec_info
->sector_bits
[num_sectors
++] = i
+ 32;
329 /* flash bank str9x <base> <size> 0 0 <target#>
331 int str9xpec_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
333 str9xpec_flash_controller_t
*str9xpec_info
;
334 armv4_5_common_t
*armv4_5
= NULL
;
335 arm7_9_common_t
*arm7_9
= NULL
;
336 arm_jtag_t
*jtag_info
= NULL
;
340 LOG_WARNING("incomplete flash_bank str9x configuration");
341 return ERROR_FLASH_BANK_INVALID
;
344 str9xpec_info
= malloc(sizeof(str9xpec_flash_controller_t
));
345 bank
->driver_priv
= str9xpec_info
;
347 /* find out jtag position of flash controller
348 * it is always after the arm966 core */
350 armv4_5
= bank
->target
->arch_info
;
351 arm7_9
= armv4_5
->arch_info
;
352 jtag_info
= &arm7_9
->jtag_info
;
354 str9xpec_info
->chain_pos
= (jtag_info
->chain_pos
- 1);
355 str9xpec_info
->isc_enable
= 0;
356 str9xpec_info
->devarm
= NULL
;
358 str9xpec_build_block_list(bank
);
360 /* clear option byte register */
361 buf_set_u32(str9xpec_info
->options
, 0, 64, 0);
366 int str9xpec_blank_check(struct flash_bank_s
*bank
, int first
, int last
)
374 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
376 chain_pos
= str9xpec_info
->chain_pos
;
378 if (!str9xpec_info
->isc_enable
) {
379 str9xpec_isc_enable( bank
);
382 if (!str9xpec_info
->isc_enable
) {
383 return ERROR_FLASH_OPERATION_FAILED
;
386 buffer
= calloc(CEIL(64, 8), 1);
388 LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first
, last
);
390 for (i
= first
; i
<= last
; i
++) {
391 buf_set_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1, 1);
394 /* execute ISC_BLANK_CHECK command */
395 str9xpec_set_instr(chain_pos
, ISC_BLANK_CHECK
, TAP_PI
);
397 field
.device
= chain_pos
;
399 field
.out_value
= buffer
;
400 field
.out_mask
= NULL
;
401 field
.in_value
= NULL
;
402 field
.in_check_value
= NULL
;
403 field
.in_check_mask
= NULL
;
404 field
.in_handler
= NULL
;
405 field
.in_handler_priv
= NULL
;
407 jtag_add_dr_scan(1, &field
, TAP_RTI
);
408 jtag_add_sleep(40000);
410 /* read blank check result */
411 field
.device
= chain_pos
;
413 field
.out_value
= NULL
;
414 field
.out_mask
= NULL
;
415 field
.in_value
= buffer
;
416 field
.in_check_value
= NULL
;
417 field
.in_check_mask
= NULL
;
418 field
.in_handler
= NULL
;
419 field
.in_handler_priv
= NULL
;
421 jtag_add_dr_scan(1, &field
, TAP_PI
);
422 jtag_execute_queue();
424 status
= str9xpec_isc_status(chain_pos
);
426 for (i
= first
; i
<= last
; i
++)
428 if (buf_get_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1))
429 bank
->sectors
[i
].is_erased
= 0;
431 bank
->sectors
[i
].is_erased
= 1;
436 str9xpec_isc_disable(bank
);
438 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
439 return ERROR_FLASH_OPERATION_FAILED
;
443 int str9xpec_protect_check(struct flash_bank_s
*bank
)
448 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
450 status
= str9xpec_read_config(bank
);
452 for (i
= 0; i
< bank
->num_sectors
; i
++)
454 if (buf_get_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1))
455 bank
->sectors
[i
].is_protected
= 1;
457 bank
->sectors
[i
].is_protected
= 0;
460 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
461 return ERROR_FLASH_OPERATION_FAILED
;
465 int str9xpec_erase_area(struct flash_bank_s
*bank
, int first
, int last
)
473 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
475 chain_pos
= str9xpec_info
->chain_pos
;
477 if (!str9xpec_info
->isc_enable
) {
478 str9xpec_isc_enable( bank
);
481 if (!str9xpec_info
->isc_enable
) {
482 return ISC_STATUS_ERROR
;
485 buffer
= calloc(CEIL(64, 8), 1);
487 LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first
, last
);
489 /* last bank: 0xFF signals a full erase (unlock complete device) */
490 /* last bank: 0xFE signals a option byte erase */
493 for (i
= 0; i
< 64; i
++) {
494 buf_set_u32(buffer
, i
, 1, 1);
497 else if (last
== 0xFE)
499 buf_set_u32(buffer
, 49, 1, 1);
503 for (i
= first
; i
<= last
; i
++) {
504 buf_set_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1, 1);
508 LOG_DEBUG("ISC_ERASE");
510 /* execute ISC_ERASE command */
511 str9xpec_set_instr(chain_pos
, ISC_ERASE
, TAP_PI
);
513 field
.device
= chain_pos
;
515 field
.out_value
= buffer
;
516 field
.out_mask
= NULL
;
517 field
.in_value
= NULL
;
518 field
.in_check_value
= NULL
;
519 field
.in_check_mask
= NULL
;
520 field
.in_handler
= NULL
;
521 field
.in_handler_priv
= NULL
;
523 jtag_add_dr_scan(1, &field
, TAP_RTI
);
524 jtag_execute_queue();
528 /* wait for erase completion */
529 while (!((status
= str9xpec_isc_status(chain_pos
)) & ISC_STATUS_BUSY
)) {
535 str9xpec_isc_disable(bank
);
540 int str9xpec_erase(struct flash_bank_s
*bank
, int first
, int last
)
544 status
= str9xpec_erase_area(bank
, first
, last
);
546 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
547 return ERROR_FLASH_OPERATION_FAILED
;
552 int str9xpec_lock_device(struct flash_bank_s
*bank
)
557 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
559 str9xpec_info
= bank
->driver_priv
;
560 chain_pos
= str9xpec_info
->chain_pos
;
562 if (!str9xpec_info
->isc_enable
) {
563 str9xpec_isc_enable( bank
);
566 if (!str9xpec_info
->isc_enable
) {
567 return ISC_STATUS_ERROR
;
570 /* set security address */
571 str9xpec_set_address(bank
, 0x80);
573 /* execute ISC_PROGRAM command */
574 str9xpec_set_instr(chain_pos
, ISC_PROGRAM_SECURITY
, TAP_RTI
);
576 str9xpec_set_instr(chain_pos
, ISC_NOOP
, TAP_PI
);
579 field
.device
= chain_pos
;
581 field
.out_value
= NULL
;
582 field
.out_mask
= NULL
;
583 field
.in_value
= &status
;
584 field
.in_check_value
= NULL
;
585 field
.in_check_mask
= NULL
;
586 field
.in_handler
= NULL
;
587 field
.in_handler_priv
= NULL
;
589 jtag_add_dr_scan(1, &field
, -1);
590 jtag_execute_queue();
592 } while(!(status
& ISC_STATUS_BUSY
));
594 str9xpec_isc_disable(bank
);
599 int str9xpec_unlock_device(struct flash_bank_s
*bank
)
603 status
= str9xpec_erase_area(bank
, 0, 255);
608 int str9xpec_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
613 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
615 status
= str9xpec_read_config(bank
);
617 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
618 return ERROR_FLASH_OPERATION_FAILED
;
620 LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first
, last
);
622 /* last bank: 0xFF signals a full device protect */
627 status
= str9xpec_lock_device(bank
);
631 /* perform full erase to unlock device */
632 status
= str9xpec_unlock_device(bank
);
637 for (i
= first
; i
<= last
; i
++)
640 buf_set_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1, 1);
642 buf_set_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1, 0);
645 status
= str9xpec_write_options(bank
);
648 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
649 return ERROR_FLASH_OPERATION_FAILED
;
654 int str9xpec_set_address(struct flash_bank_s
*bank
, u8 sector
)
658 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
660 chain_pos
= str9xpec_info
->chain_pos
;
662 /* set flash controller address */
663 str9xpec_set_instr(chain_pos
, ISC_ADDRESS_SHIFT
, TAP_PI
);
665 field
.device
= chain_pos
;
667 field
.out_value
= §or
;
668 field
.out_mask
= NULL
;
669 field
.in_value
= NULL
;
670 field
.in_check_value
= NULL
;
671 field
.in_check_mask
= NULL
;
672 field
.in_handler
= NULL
;
673 field
.in_handler_priv
= NULL
;
675 jtag_add_dr_scan(1, &field
, -1);
680 int str9xpec_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
682 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
683 u32 dwords_remaining
= (count
/ 8);
684 u32 bytes_remaining
= (count
& 0x00000007);
685 u32 bytes_written
= 0;
687 u32 check_address
= offset
;
692 u32 first_sector
= 0;
695 chain_pos
= str9xpec_info
->chain_pos
;
697 if (!str9xpec_info
->isc_enable
) {
698 str9xpec_isc_enable(bank
);
701 if (!str9xpec_info
->isc_enable
) {
702 return ERROR_FLASH_OPERATION_FAILED
;
707 LOG_WARNING("offset 0x%x breaks required 8-byte alignment", offset
);
708 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
711 for (i
= 0; i
< bank
->num_sectors
; i
++)
713 u32 sec_start
= bank
->sectors
[i
].offset
;
714 u32 sec_end
= sec_start
+ bank
->sectors
[i
].size
;
716 /* check if destination falls within the current sector */
717 if ((check_address
>= sec_start
) && (check_address
< sec_end
))
719 /* check if destination ends in the current sector */
720 if (offset
+ count
< sec_end
)
721 check_address
= offset
+ count
;
723 check_address
= sec_end
;
726 if ((offset
>= sec_start
) && (offset
< sec_end
)){
730 if ((offset
+ count
>= sec_start
) && (offset
+ count
< sec_end
)){
735 if (check_address
!= offset
+ count
)
736 return ERROR_FLASH_DST_OUT_OF_BANK
;
738 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector
, last_sector
);
740 scanbuf
= calloc(CEIL(64, 8), 1);
742 LOG_DEBUG("ISC_PROGRAM");
744 for (i
= first_sector
; i
<= last_sector
; i
++)
746 str9xpec_set_address(bank
, str9xpec_info
->sector_bits
[i
]);
748 dwords_remaining
= dwords_remaining
< (bank
->sectors
[i
].size
/8) ? dwords_remaining
: (bank
->sectors
[i
].size
/8);
750 while (dwords_remaining
> 0)
752 str9xpec_set_instr(chain_pos
, ISC_PROGRAM
, TAP_PI
);
754 field
.device
= chain_pos
;
756 field
.out_value
= (buffer
+ bytes_written
);
757 field
.out_mask
= NULL
;
758 field
.in_value
= NULL
;
759 field
.in_check_value
= NULL
;
760 field
.in_check_mask
= NULL
;
761 field
.in_handler
= NULL
;
762 field
.in_handler_priv
= NULL
;
764 jtag_add_dr_scan(1, &field
, TAP_RTI
);
766 /* small delay before polling */
769 str9xpec_set_instr(chain_pos
, ISC_NOOP
, TAP_PI
);
772 field
.device
= chain_pos
;
774 field
.out_value
= NULL
;
775 field
.out_mask
= NULL
;
776 field
.in_value
= scanbuf
;
777 field
.in_check_value
= NULL
;
778 field
.in_check_mask
= NULL
;
779 field
.in_handler
= NULL
;
780 field
.in_handler_priv
= NULL
;
782 jtag_add_dr_scan(1, &field
, -1);
783 jtag_execute_queue();
785 status
= buf_get_u32(scanbuf
, 0, 8);
787 } while(!(status
& ISC_STATUS_BUSY
));
789 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
790 return ERROR_FLASH_OPERATION_FAILED
;
792 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
793 return ERROR_FLASH_OPERATION_FAILED; */
802 u8 last_dword
[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
805 while(bytes_remaining
> 0)
807 last_dword
[i
++] = *(buffer
+ bytes_written
);
812 str9xpec_set_instr(chain_pos
, ISC_PROGRAM
, TAP_PI
);
814 field
.device
= chain_pos
;
816 field
.out_value
= last_dword
;
817 field
.out_mask
= NULL
;
818 field
.in_value
= NULL
;
819 field
.in_check_value
= NULL
;
820 field
.in_check_mask
= NULL
;
821 field
.in_handler
= NULL
;
822 field
.in_handler_priv
= NULL
;
824 jtag_add_dr_scan(1, &field
, TAP_RTI
);
826 /* small delay before polling */
829 str9xpec_set_instr(chain_pos
, ISC_NOOP
, TAP_PI
);
832 field
.device
= chain_pos
;
834 field
.out_value
= NULL
;
835 field
.out_mask
= NULL
;
836 field
.in_value
= scanbuf
;
837 field
.in_check_value
= NULL
;
838 field
.in_check_mask
= NULL
;
839 field
.in_handler
= NULL
;
840 field
.in_handler_priv
= NULL
;
842 jtag_add_dr_scan(1, &field
, -1);
843 jtag_execute_queue();
845 status
= buf_get_u32(scanbuf
, 0, 8);
847 } while(!(status
& ISC_STATUS_BUSY
));
849 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
850 return ERROR_FLASH_OPERATION_FAILED
;
852 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
853 return ERROR_FLASH_OPERATION_FAILED; */
858 str9xpec_isc_disable(bank
);
863 int str9xpec_probe(struct flash_bank_s
*bank
)
868 int str9xpec_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
875 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
879 return ERROR_COMMAND_SYNTAX_ERROR
;
882 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
885 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
889 str9xpec_info
= bank
->driver_priv
;
890 chain_pos
= str9xpec_info
->chain_pos
;
892 buffer
= calloc(CEIL(32, 8), 1);
894 str9xpec_set_instr(chain_pos
, ISC_IDCODE
, TAP_PI
);
896 field
.device
= chain_pos
;
898 field
.out_value
= NULL
;
899 field
.out_mask
= NULL
;
900 field
.in_value
= buffer
;
901 field
.in_check_value
= NULL
;
902 field
.in_check_mask
= NULL
;
903 field
.in_handler
= NULL
;
904 field
.in_handler_priv
= NULL
;
906 jtag_add_dr_scan(1, &field
, TAP_RTI
);
907 jtag_execute_queue();
909 idcode
= buf_get_u32(buffer
, 0, 32);
911 command_print(cmd_ctx
, "str9xpec part id: 0x%8.8x", idcode
);
918 int str9xpec_erase_check(struct flash_bank_s
*bank
)
920 return str9xpec_blank_check(bank
, 0, bank
->num_sectors
- 1);
923 int str9xpec_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
925 snprintf(buf
, buf_size
, "str9xpec flash driver info" );
929 int str9xpec_handle_flash_options_read_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
933 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
937 command_print(cmd_ctx
, "str9xpec options_read <bank>");
941 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
944 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
948 str9xpec_info
= bank
->driver_priv
;
950 status
= str9xpec_read_config(bank
);
952 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
953 return ERROR_FLASH_OPERATION_FAILED
;
956 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1))
957 command_print(cmd_ctx
, "CS Map: bank1");
959 command_print(cmd_ctx
, "CS Map: bank0");
962 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_OTPBIT
, 1))
963 command_print(cmd_ctx
, "OTP Lock: OTP Locked");
965 command_print(cmd_ctx
, "OTP Lock: OTP Unlocked");
968 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1))
969 command_print(cmd_ctx
, "LVD Threshold: 2.7v");
971 command_print(cmd_ctx
, "LVD Threshold: 2.4v");
973 /* LVD reset warning */
974 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1))
975 command_print(cmd_ctx
, "LVD Reset Warning: VDD or VDDQ Inputs");
977 command_print(cmd_ctx
, "LVD Reset Warning: VDD Input Only");
979 /* LVD reset select */
980 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1))
981 command_print(cmd_ctx
, "LVD Reset Selection: VDD or VDDQ Inputs");
983 command_print(cmd_ctx
, "LVD Reset Selection: VDD Input Only");
988 int str9xpec_write_options(struct flash_bank_s
*bank
)
993 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
995 str9xpec_info
= bank
->driver_priv
;
996 chain_pos
= str9xpec_info
->chain_pos
;
998 /* erase config options first */
999 status
= str9xpec_erase_area( bank
, 0xFE, 0xFE );
1001 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1004 if (!str9xpec_info
->isc_enable
) {
1005 str9xpec_isc_enable( bank
);
1008 if (!str9xpec_info
->isc_enable
) {
1009 return ISC_STATUS_ERROR
;
1012 /* according to data 64th bit has to be set */
1013 buf_set_u32(str9xpec_info
->options
, 63, 1, 1);
1015 /* set option byte address */
1016 str9xpec_set_address(bank
, 0x50);
1018 /* execute ISC_PROGRAM command */
1019 str9xpec_set_instr(chain_pos
, ISC_PROGRAM
, TAP_PI
);
1021 field
.device
= chain_pos
;
1022 field
.num_bits
= 64;
1023 field
.out_value
= str9xpec_info
->options
;
1024 field
.out_mask
= NULL
;
1025 field
.in_value
= NULL
;
1026 field
.in_check_value
= NULL
;
1027 field
.in_check_mask
= NULL
;
1028 field
.in_handler
= NULL
;
1029 field
.in_handler_priv
= NULL
;
1031 jtag_add_dr_scan(1, &field
, TAP_RTI
);
1033 /* small delay before polling */
1036 str9xpec_set_instr(chain_pos
, ISC_NOOP
, TAP_PI
);
1039 field
.device
= chain_pos
;
1041 field
.out_value
= NULL
;
1042 field
.out_mask
= NULL
;
1043 field
.in_value
= &status
;
1044 field
.in_check_value
= NULL
;
1045 field
.in_check_mask
= NULL
;
1046 field
.in_handler
= NULL
;
1047 field
.in_handler_priv
= NULL
;
1049 jtag_add_dr_scan(1, &field
, -1);
1050 jtag_execute_queue();
1052 } while(!(status
& ISC_STATUS_BUSY
));
1054 str9xpec_isc_disable(bank
);
1059 int str9xpec_handle_flash_options_write_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1066 command_print(cmd_ctx
, "str9xpec options_write <bank>");
1070 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1073 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1077 status
= str9xpec_write_options(bank
);
1079 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1080 return ERROR_FLASH_OPERATION_FAILED
;
1085 int str9xpec_handle_flash_options_cmap_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1088 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1092 command_print(cmd_ctx
, "str9xpec options_cmap <bank> <bank0|bank1>");
1096 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1099 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1103 str9xpec_info
= bank
->driver_priv
;
1105 if (strcmp(args
[1], "bank1") == 0)
1107 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 1);
1111 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 0);
1117 int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1120 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1124 command_print(cmd_ctx
, "str9xpec options_lvdthd <bank> <2.4v|2.7v>");
1128 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1131 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1135 str9xpec_info
= bank
->driver_priv
;
1137 if (strcmp(args
[1], "2.7v") == 0)
1139 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 1);
1143 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 0);
1149 int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1152 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1156 command_print(cmd_ctx
, "str9xpec options_lvdsel <bank> <vdd|vdd_vddq>");
1160 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1163 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1167 str9xpec_info
= bank
->driver_priv
;
1169 if (strcmp(args
[1], "vdd_vddq") == 0)
1171 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 1);
1175 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 0);
1181 int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1184 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1188 command_print(cmd_ctx
, "str9xpec options_lvdwarn <bank> <vdd|vdd_vddq>");
1192 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1195 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1199 str9xpec_info
= bank
->driver_priv
;
1201 if (strcmp(args
[1], "vdd_vddq") == 0)
1203 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 1);
1207 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 0);
1213 int str9xpec_handle_flash_lock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1220 command_print(cmd_ctx
, "str9xpec lock <bank>");
1224 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1227 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1231 status
= str9xpec_lock_device(bank
);
1233 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1234 return ERROR_FLASH_OPERATION_FAILED
;
1239 int str9xpec_handle_flash_unlock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1246 command_print(cmd_ctx
, "str9xpec unlock <bank>");
1250 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1253 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1257 status
= str9xpec_unlock_device(bank
);
1259 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1260 return ERROR_FLASH_OPERATION_FAILED
;
1265 int str9xpec_handle_flash_enable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1269 jtag_device_t
* dev0
;
1270 jtag_device_t
* dev2
;
1271 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1275 command_print(cmd_ctx
, "str9xpec enable_turbo <bank>");
1279 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1282 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1286 str9xpec_info
= bank
->driver_priv
;
1288 chain_pos
= str9xpec_info
->chain_pos
;
1290 /* remove arm core from chain - enter turbo mode */
1292 str9xpec_set_instr(chain_pos
+2, 0xD, TAP_RTI
);
1293 jtag_execute_queue();
1295 /* modify scan chain - str9 core has been removed */
1296 dev0
= jtag_get_device(chain_pos
);
1297 str9xpec_info
->devarm
= jtag_get_device(chain_pos
+1);
1298 dev2
= jtag_get_device(chain_pos
+2);
1305 int str9xpec_handle_flash_disable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1309 jtag_device_t
* dev0
;
1310 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1314 command_print(cmd_ctx
, "str9xpec disable_turbo <bank>");
1318 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1321 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1325 str9xpec_info
= bank
->driver_priv
;
1327 chain_pos
= str9xpec_info
->chain_pos
;
1329 dev0
= jtag_get_device(chain_pos
);
1331 /* exit turbo mode via TLR */
1332 str9xpec_set_instr(chain_pos
, ISC_NOOP
, TAP_TLR
);
1333 jtag_execute_queue();
1335 /* restore previous scan chain */
1336 if( str9xpec_info
->devarm
) {
1337 dev0
->next
= str9xpec_info
->devarm
;
1339 str9xpec_info
->devarm
= NULL
;