1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
29 #include <target/arm7_9_common.h>
33 #define ISC_IDCODE 0xFE
34 #define ISC_MFG_READ 0x4C
35 #define ISC_CONFIGURATION 0x07
36 #define ISC_ENABLE 0x0C
37 #define ISC_DISABLE 0x0F
39 #define ISC_ADDRESS_SHIFT 0x11
40 #define ISC_CLR_STATUS 0x13
41 #define ISC_PROGRAM 0x20
42 #define ISC_PROGRAM_SECURITY 0x22
43 #define ISC_PROGRAM_UC 0x23
44 #define ISC_ERASE 0x30
46 #define ISC_BLANK_CHECK 0x60
48 /* ISC_DEFAULT bit definitions */
50 #define ISC_STATUS_SECURITY 0x40
51 #define ISC_STATUS_INT_ERROR 0x30
52 #define ISC_STATUS_MODE 0x08
53 #define ISC_STATUS_BUSY 0x04
54 #define ISC_STATUS_ERROR 0x03
56 /* Option bytes definitions */
58 #define STR9XPEC_OPT_CSMAPBIT 48
59 #define STR9XPEC_OPT_LVDTHRESBIT 49
60 #define STR9XPEC_OPT_LVDSELBIT 50
61 #define STR9XPEC_OPT_LVDWARNBIT 51
62 #define STR9XPEC_OPT_OTPBIT 63
64 enum str9xpec_status_codes
{
65 STR9XPEC_INVALID_COMMAND
= 1,
66 STR9XPEC_ISC_SUCCESS
= 2,
67 STR9XPEC_ISC_DISABLED
= 3,
68 STR9XPEC_ISC_INTFAIL
= 32,
71 struct str9xpec_flash_controller
{
73 uint32_t *sector_bits
;
79 static int str9xpec_erase_area(struct flash_bank
*bank
, int first
, int last
);
80 static int str9xpec_set_address(struct flash_bank
*bank
, uint8_t sector
);
81 static int str9xpec_write_options(struct flash_bank
*bank
);
83 static int str9xpec_set_instr(struct jtag_tap
*tap
, uint32_t new_instr
, tap_state_t end_state
)
86 return ERROR_TARGET_INVALID
;
88 if (buf_get_u32(tap
->cur_instr
, 0, tap
->ir_length
) != new_instr
) {
89 struct scan_field field
;
91 field
.num_bits
= tap
->ir_length
;
92 void *t
= calloc(DIV_ROUND_UP(field
.num_bits
, 8), 1);
94 buf_set_u32(t
, 0, field
.num_bits
, new_instr
);
95 field
.in_value
= NULL
;
97 jtag_add_ir_scan(tap
, &field
, end_state
);
105 static uint8_t str9xpec_isc_status(struct jtag_tap
*tap
)
107 struct scan_field field
;
110 if (str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
) != ERROR_OK
)
111 return ISC_STATUS_ERROR
;
114 field
.out_value
= NULL
;
115 field
.in_value
= &status
;
118 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
119 jtag_execute_queue();
121 LOG_DEBUG("status: 0x%2.2x", status
);
123 if (status
& ISC_STATUS_SECURITY
)
124 LOG_INFO("Device Security Bit Set");
129 static int str9xpec_isc_enable(struct flash_bank
*bank
)
132 struct jtag_tap
*tap
;
133 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
135 tap
= str9xpec_info
->tap
;
137 if (str9xpec_info
->isc_enable
)
141 if (str9xpec_set_instr(tap
, ISC_ENABLE
, TAP_IDLE
) != ERROR_OK
)
142 return ERROR_TARGET_INVALID
;
144 /* check ISC status */
145 status
= str9xpec_isc_status(tap
);
146 if (status
& ISC_STATUS_MODE
) {
147 /* we have entered isc mode */
148 str9xpec_info
->isc_enable
= 1;
149 LOG_DEBUG("ISC_MODE Enabled");
155 static int str9xpec_isc_disable(struct flash_bank
*bank
)
158 struct jtag_tap
*tap
;
159 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
161 tap
= str9xpec_info
->tap
;
163 if (!str9xpec_info
->isc_enable
)
166 if (str9xpec_set_instr(tap
, ISC_DISABLE
, TAP_IDLE
) != ERROR_OK
)
167 return ERROR_TARGET_INVALID
;
169 /* delay to handle aborts */
172 /* check ISC status */
173 status
= str9xpec_isc_status(tap
);
174 if (!(status
& ISC_STATUS_MODE
)) {
175 /* we have left isc mode */
176 str9xpec_info
->isc_enable
= 0;
177 LOG_DEBUG("ISC_MODE Disabled");
183 static int str9xpec_read_config(struct flash_bank
*bank
)
185 struct scan_field field
;
187 struct jtag_tap
*tap
;
189 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
191 tap
= str9xpec_info
->tap
;
193 LOG_DEBUG("ISC_CONFIGURATION");
195 /* execute ISC_CONFIGURATION command */
196 str9xpec_set_instr(tap
, ISC_CONFIGURATION
, TAP_IRPAUSE
);
199 field
.out_value
= NULL
;
200 field
.in_value
= str9xpec_info
->options
;
203 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
204 jtag_execute_queue();
206 status
= str9xpec_isc_status(tap
);
211 static int str9xpec_build_block_list(struct flash_bank
*bank
)
213 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
217 int b0_sectors
= 0, b1_sectors
= 0;
219 int b1_size
= 0x2000;
221 switch (bank
->size
) {
242 LOG_ERROR("BUG: unknown bank->size encountered");
246 num_sectors
= b0_sectors
+ b1_sectors
;
248 bank
->num_sectors
= num_sectors
;
249 bank
->sectors
= malloc(sizeof(struct flash_sector
) * num_sectors
);
250 str9xpec_info
->sector_bits
= malloc(sizeof(uint32_t) * num_sectors
);
254 for (i
= 0; i
< b0_sectors
; i
++) {
255 bank
->sectors
[num_sectors
].offset
= offset
;
256 bank
->sectors
[num_sectors
].size
= 0x10000;
257 offset
+= bank
->sectors
[i
].size
;
258 bank
->sectors
[num_sectors
].is_erased
= -1;
259 bank
->sectors
[num_sectors
].is_protected
= 1;
260 str9xpec_info
->sector_bits
[num_sectors
++] = i
;
263 for (i
= 0; i
< b1_sectors
; i
++) {
264 bank
->sectors
[num_sectors
].offset
= offset
;
265 bank
->sectors
[num_sectors
].size
= b1_size
;
266 offset
+= bank
->sectors
[i
].size
;
267 bank
->sectors
[num_sectors
].is_erased
= -1;
268 bank
->sectors
[num_sectors
].is_protected
= 1;
269 str9xpec_info
->sector_bits
[num_sectors
++] = i
+ 32;
275 /* flash bank str9x <base> <size> 0 0 <target#>
277 FLASH_BANK_COMMAND_HANDLER(str9xpec_flash_bank_command
)
279 struct str9xpec_flash_controller
*str9xpec_info
;
280 struct arm
*arm
= NULL
;
281 struct arm7_9_common
*arm7_9
= NULL
;
282 struct arm_jtag
*jtag_info
= NULL
;
285 return ERROR_COMMAND_SYNTAX_ERROR
;
287 str9xpec_info
= malloc(sizeof(struct str9xpec_flash_controller
));
288 bank
->driver_priv
= str9xpec_info
;
290 /* REVISIT verify that the jtag position of flash controller is
291 * right after *THIS* core, which must be a STR9xx core ...
293 arm
= bank
->target
->arch_info
;
294 arm7_9
= arm
->arch_info
;
295 jtag_info
= &arm7_9
->jtag_info
;
297 /* The core is the next tap after the flash controller in the chain */
298 str9xpec_info
->tap
= jtag_tap_by_position(jtag_info
->tap
->abs_chain_position
- 1);
299 str9xpec_info
->isc_enable
= 0;
301 str9xpec_build_block_list(bank
);
303 /* clear option byte register */
304 buf_set_u32(str9xpec_info
->options
, 0, 64, 0);
309 static int str9xpec_blank_check(struct flash_bank
*bank
, int first
, int last
)
311 struct scan_field field
;
313 struct jtag_tap
*tap
;
315 uint8_t *buffer
= NULL
;
317 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
319 tap
= str9xpec_info
->tap
;
321 if (!str9xpec_info
->isc_enable
)
322 str9xpec_isc_enable(bank
);
324 if (!str9xpec_info
->isc_enable
)
325 return ERROR_FLASH_OPERATION_FAILED
;
327 buffer
= calloc(DIV_ROUND_UP(64, 8), 1);
329 LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first
, last
);
331 for (i
= first
; i
<= last
; i
++)
332 buf_set_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1, 1);
334 /* execute ISC_BLANK_CHECK command */
335 str9xpec_set_instr(tap
, ISC_BLANK_CHECK
, TAP_IRPAUSE
);
338 field
.out_value
= buffer
;
339 field
.in_value
= NULL
;
341 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
342 jtag_add_sleep(40000);
344 /* read blank check result */
346 field
.out_value
= NULL
;
347 field
.in_value
= buffer
;
349 jtag_add_dr_scan(tap
, 1, &field
, TAP_IRPAUSE
);
350 jtag_execute_queue();
352 status
= str9xpec_isc_status(tap
);
354 for (i
= first
; i
<= last
; i
++) {
355 if (buf_get_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1))
356 bank
->sectors
[i
].is_erased
= 0;
358 bank
->sectors
[i
].is_erased
= 1;
363 str9xpec_isc_disable(bank
);
365 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
366 return ERROR_FLASH_OPERATION_FAILED
;
370 static int str9xpec_protect_check(struct flash_bank
*bank
)
375 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
377 status
= str9xpec_read_config(bank
);
379 for (i
= 0; i
< bank
->num_sectors
; i
++) {
380 if (buf_get_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1))
381 bank
->sectors
[i
].is_protected
= 1;
383 bank
->sectors
[i
].is_protected
= 0;
386 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
387 return ERROR_FLASH_OPERATION_FAILED
;
391 static int str9xpec_erase_area(struct flash_bank
*bank
, int first
, int last
)
393 struct scan_field field
;
395 struct jtag_tap
*tap
;
397 uint8_t *buffer
= NULL
;
399 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
401 tap
= str9xpec_info
->tap
;
403 if (!str9xpec_info
->isc_enable
)
404 str9xpec_isc_enable(bank
);
406 if (!str9xpec_info
->isc_enable
)
407 return ISC_STATUS_ERROR
;
409 buffer
= calloc(DIV_ROUND_UP(64, 8), 1);
411 LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first
, last
);
413 /* last bank: 0xFF signals a full erase (unlock complete device) */
414 /* last bank: 0xFE signals a option byte erase */
416 for (i
= 0; i
< 64; i
++)
417 buf_set_u32(buffer
, i
, 1, 1);
418 } else if (last
== 0xFE)
419 buf_set_u32(buffer
, 49, 1, 1);
421 for (i
= first
; i
<= last
; i
++)
422 buf_set_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1, 1);
425 LOG_DEBUG("ISC_ERASE");
427 /* execute ISC_ERASE command */
428 str9xpec_set_instr(tap
, ISC_ERASE
, TAP_IRPAUSE
);
431 field
.out_value
= buffer
;
432 field
.in_value
= NULL
;
434 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
435 jtag_execute_queue();
439 /* wait for erase completion */
440 while (!((status
= str9xpec_isc_status(tap
)) & ISC_STATUS_BUSY
))
445 str9xpec_isc_disable(bank
);
450 static int str9xpec_erase(struct flash_bank
*bank
, int first
, int last
)
454 status
= str9xpec_erase_area(bank
, first
, last
);
456 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
457 return ERROR_FLASH_OPERATION_FAILED
;
462 static int str9xpec_lock_device(struct flash_bank
*bank
)
464 struct scan_field field
;
466 struct jtag_tap
*tap
;
467 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
469 str9xpec_info
= bank
->driver_priv
;
470 tap
= str9xpec_info
->tap
;
472 if (!str9xpec_info
->isc_enable
)
473 str9xpec_isc_enable(bank
);
475 if (!str9xpec_info
->isc_enable
)
476 return ISC_STATUS_ERROR
;
478 /* set security address */
479 str9xpec_set_address(bank
, 0x80);
481 /* execute ISC_PROGRAM command */
482 str9xpec_set_instr(tap
, ISC_PROGRAM_SECURITY
, TAP_IDLE
);
484 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
488 field
.out_value
= NULL
;
489 field
.in_value
= &status
;
491 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
492 jtag_execute_queue();
494 } while (!(status
& ISC_STATUS_BUSY
));
496 str9xpec_isc_disable(bank
);
501 static int str9xpec_unlock_device(struct flash_bank
*bank
)
505 status
= str9xpec_erase_area(bank
, 0, 255);
510 static int str9xpec_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
515 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
517 status
= str9xpec_read_config(bank
);
519 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
520 return ERROR_FLASH_OPERATION_FAILED
;
522 LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first
, last
);
524 /* last bank: 0xFF signals a full device protect */
527 status
= str9xpec_lock_device(bank
);
529 /* perform full erase to unlock device */
530 status
= str9xpec_unlock_device(bank
);
533 for (i
= first
; i
<= last
; i
++) {
535 buf_set_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1, 1);
537 buf_set_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1, 0);
540 status
= str9xpec_write_options(bank
);
543 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
544 return ERROR_FLASH_OPERATION_FAILED
;
549 static int str9xpec_set_address(struct flash_bank
*bank
, uint8_t sector
)
551 struct jtag_tap
*tap
;
552 struct scan_field field
;
553 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
555 tap
= str9xpec_info
->tap
;
557 /* set flash controller address */
558 str9xpec_set_instr(tap
, ISC_ADDRESS_SHIFT
, TAP_IRPAUSE
);
561 field
.out_value
= §or
;
562 field
.in_value
= NULL
;
564 jtag_add_dr_scan(tap
, 1, &field
, TAP_IRPAUSE
);
569 static int str9xpec_write(struct flash_bank
*bank
, uint8_t *buffer
,
570 uint32_t offset
, uint32_t count
)
572 struct str9xpec_flash_controller
*str9xpec_info
= bank
->driver_priv
;
573 uint32_t dwords_remaining
= (count
/ 8);
574 uint32_t bytes_remaining
= (count
& 0x00000007);
575 uint32_t bytes_written
= 0;
577 uint32_t check_address
= offset
;
578 struct jtag_tap
*tap
;
579 struct scan_field field
;
582 int first_sector
= 0;
585 tap
= str9xpec_info
->tap
;
587 if (!str9xpec_info
->isc_enable
)
588 str9xpec_isc_enable(bank
);
590 if (!str9xpec_info
->isc_enable
)
591 return ERROR_FLASH_OPERATION_FAILED
;
594 LOG_WARNING("offset 0x%" PRIx32
" breaks required 8-byte alignment", offset
);
595 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
598 for (i
= 0; i
< bank
->num_sectors
; i
++) {
599 uint32_t sec_start
= bank
->sectors
[i
].offset
;
600 uint32_t sec_end
= sec_start
+ bank
->sectors
[i
].size
;
602 /* check if destination falls within the current sector */
603 if ((check_address
>= sec_start
) && (check_address
< sec_end
)) {
604 /* check if destination ends in the current sector */
605 if (offset
+ count
< sec_end
)
606 check_address
= offset
+ count
;
608 check_address
= sec_end
;
611 if ((offset
>= sec_start
) && (offset
< sec_end
))
614 if ((offset
+ count
>= sec_start
) && (offset
+ count
< sec_end
))
618 if (check_address
!= offset
+ count
)
619 return ERROR_FLASH_DST_OUT_OF_BANK
;
621 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector
, last_sector
);
623 scanbuf
= calloc(DIV_ROUND_UP(64, 8), 1);
625 LOG_DEBUG("ISC_PROGRAM");
627 for (i
= first_sector
; i
<= last_sector
; i
++) {
628 str9xpec_set_address(bank
, str9xpec_info
->sector_bits
[i
]);
630 dwords_remaining
= dwords_remaining
< (bank
->sectors
[i
].size
/8)
631 ? dwords_remaining
: (bank
->sectors
[i
].size
/8);
633 while (dwords_remaining
> 0) {
634 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
637 field
.out_value
= (buffer
+ bytes_written
);
638 field
.in_value
= NULL
;
640 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
642 /* small delay before polling */
645 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
649 field
.out_value
= NULL
;
650 field
.in_value
= scanbuf
;
652 jtag_add_dr_scan(tap
, 1, &field
, TAP_IRPAUSE
);
653 jtag_execute_queue();
655 status
= buf_get_u32(scanbuf
, 0, 8);
657 } while (!(status
& ISC_STATUS_BUSY
));
659 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
660 return ERROR_FLASH_OPERATION_FAILED
;
662 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
663 return ERROR_FLASH_OPERATION_FAILED; */
670 if (bytes_remaining
) {
671 uint8_t last_dword
[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
673 /* copy the last remaining bytes into the write buffer */
674 memcpy(last_dword
, buffer
+bytes_written
, bytes_remaining
);
676 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
679 field
.out_value
= last_dword
;
680 field
.in_value
= NULL
;
682 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
684 /* small delay before polling */
687 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
691 field
.out_value
= NULL
;
692 field
.in_value
= scanbuf
;
694 jtag_add_dr_scan(tap
, 1, &field
, TAP_IRPAUSE
);
695 jtag_execute_queue();
697 status
= buf_get_u32(scanbuf
, 0, 8);
699 } while (!(status
& ISC_STATUS_BUSY
));
701 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
702 return ERROR_FLASH_OPERATION_FAILED
;
704 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
705 return ERROR_FLASH_OPERATION_FAILED; */
710 str9xpec_isc_disable(bank
);
715 static int str9xpec_probe(struct flash_bank
*bank
)
720 COMMAND_HANDLER(str9xpec_handle_part_id_command
)
722 struct scan_field field
;
723 uint8_t *buffer
= NULL
;
724 struct jtag_tap
*tap
;
726 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
729 return ERROR_COMMAND_SYNTAX_ERROR
;
731 struct flash_bank
*bank
;
732 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
733 if (ERROR_OK
!= retval
)
736 str9xpec_info
= bank
->driver_priv
;
737 tap
= str9xpec_info
->tap
;
739 buffer
= calloc(DIV_ROUND_UP(32, 8), 1);
741 str9xpec_set_instr(tap
, ISC_IDCODE
, TAP_IRPAUSE
);
744 field
.out_value
= NULL
;
745 field
.in_value
= buffer
;
747 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
748 jtag_execute_queue();
750 idcode
= buf_get_u32(buffer
, 0, 32);
752 command_print(CMD_CTX
, "str9xpec part id: 0x%8.8" PRIx32
"", idcode
);
759 static int str9xpec_erase_check(struct flash_bank
*bank
)
761 return str9xpec_blank_check(bank
, 0, bank
->num_sectors
- 1);
764 static int get_str9xpec_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
766 snprintf(buf
, buf_size
, "str9xpec flash driver info");
770 COMMAND_HANDLER(str9xpec_handle_flash_options_read_command
)
773 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
776 return ERROR_COMMAND_SYNTAX_ERROR
;
778 struct flash_bank
*bank
;
779 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
780 if (ERROR_OK
!= retval
)
783 str9xpec_info
= bank
->driver_priv
;
785 status
= str9xpec_read_config(bank
);
787 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
788 return ERROR_FLASH_OPERATION_FAILED
;
791 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1))
792 command_print(CMD_CTX
, "CS Map: bank1");
794 command_print(CMD_CTX
, "CS Map: bank0");
797 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_OTPBIT
, 1))
798 command_print(CMD_CTX
, "OTP Lock: OTP Locked");
800 command_print(CMD_CTX
, "OTP Lock: OTP Unlocked");
803 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1))
804 command_print(CMD_CTX
, "LVD Threshold: 2.7v");
806 command_print(CMD_CTX
, "LVD Threshold: 2.4v");
808 /* LVD reset warning */
809 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1))
810 command_print(CMD_CTX
, "LVD Reset Warning: VDD or VDDQ Inputs");
812 command_print(CMD_CTX
, "LVD Reset Warning: VDD Input Only");
814 /* LVD reset select */
815 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1))
816 command_print(CMD_CTX
, "LVD Reset Selection: VDD or VDDQ Inputs");
818 command_print(CMD_CTX
, "LVD Reset Selection: VDD Input Only");
823 static int str9xpec_write_options(struct flash_bank
*bank
)
825 struct scan_field field
;
827 struct jtag_tap
*tap
;
828 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
830 str9xpec_info
= bank
->driver_priv
;
831 tap
= str9xpec_info
->tap
;
833 /* erase config options first */
834 status
= str9xpec_erase_area(bank
, 0xFE, 0xFE);
836 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
839 if (!str9xpec_info
->isc_enable
)
840 str9xpec_isc_enable(bank
);
842 if (!str9xpec_info
->isc_enable
)
843 return ISC_STATUS_ERROR
;
845 /* according to data 64th bit has to be set */
846 buf_set_u32(str9xpec_info
->options
, 63, 1, 1);
848 /* set option byte address */
849 str9xpec_set_address(bank
, 0x50);
851 /* execute ISC_PROGRAM command */
852 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
855 field
.out_value
= str9xpec_info
->options
;
856 field
.in_value
= NULL
;
858 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
860 /* small delay before polling */
863 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
867 field
.out_value
= NULL
;
868 field
.in_value
= &status
;
870 jtag_add_dr_scan(tap
, 1, &field
, TAP_IRPAUSE
);
871 jtag_execute_queue();
873 } while (!(status
& ISC_STATUS_BUSY
));
875 str9xpec_isc_disable(bank
);
880 COMMAND_HANDLER(str9xpec_handle_flash_options_write_command
)
885 return ERROR_COMMAND_SYNTAX_ERROR
;
887 struct flash_bank
*bank
;
888 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
889 if (ERROR_OK
!= retval
)
892 status
= str9xpec_write_options(bank
);
894 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
895 return ERROR_FLASH_OPERATION_FAILED
;
897 command_print(CMD_CTX
, "str9xpec write options complete.\n"
898 "INFO: a reset or power cycle is required "
899 "for the new settings to take effect.");
904 COMMAND_HANDLER(str9xpec_handle_flash_options_cmap_command
)
906 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
909 return ERROR_COMMAND_SYNTAX_ERROR
;
911 struct flash_bank
*bank
;
912 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
913 if (ERROR_OK
!= retval
)
916 str9xpec_info
= bank
->driver_priv
;
918 if (strcmp(CMD_ARGV
[1], "bank1") == 0)
919 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 1);
921 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 0);
926 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdthd_command
)
928 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
931 return ERROR_COMMAND_SYNTAX_ERROR
;
933 struct flash_bank
*bank
;
934 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
935 if (ERROR_OK
!= retval
)
938 str9xpec_info
= bank
->driver_priv
;
940 if (strcmp(CMD_ARGV
[1], "2.7v") == 0)
941 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 1);
943 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 0);
948 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdsel_command
)
950 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
953 return ERROR_COMMAND_SYNTAX_ERROR
;
955 struct flash_bank
*bank
;
956 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
957 if (ERROR_OK
!= retval
)
960 str9xpec_info
= bank
->driver_priv
;
962 if (strcmp(CMD_ARGV
[1], "vdd_vddq") == 0)
963 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 1);
965 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 0);
970 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdwarn_command
)
972 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
975 return ERROR_COMMAND_SYNTAX_ERROR
;
977 struct flash_bank
*bank
;
978 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
979 if (ERROR_OK
!= retval
)
982 str9xpec_info
= bank
->driver_priv
;
984 if (strcmp(CMD_ARGV
[1], "vdd_vddq") == 0)
985 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 1);
987 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 0);
992 COMMAND_HANDLER(str9xpec_handle_flash_lock_command
)
997 return ERROR_COMMAND_SYNTAX_ERROR
;
999 struct flash_bank
*bank
;
1000 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1001 if (ERROR_OK
!= retval
)
1004 status
= str9xpec_lock_device(bank
);
1006 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1007 return ERROR_FLASH_OPERATION_FAILED
;
1012 COMMAND_HANDLER(str9xpec_handle_flash_unlock_command
)
1017 return ERROR_COMMAND_SYNTAX_ERROR
;
1019 struct flash_bank
*bank
;
1020 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1021 if (ERROR_OK
!= retval
)
1024 status
= str9xpec_unlock_device(bank
);
1026 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1027 return ERROR_FLASH_OPERATION_FAILED
;
1029 command_print(CMD_CTX
, "str9xpec unlocked.\n"
1030 "INFO: a reset or power cycle is required "
1031 "for the new settings to take effect.");
1036 COMMAND_HANDLER(str9xpec_handle_flash_enable_turbo_command
)
1038 struct jtag_tap
*tap0
;
1039 struct jtag_tap
*tap1
;
1040 struct jtag_tap
*tap2
;
1041 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
1044 return ERROR_COMMAND_SYNTAX_ERROR
;
1046 struct flash_bank
*bank
;
1047 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1048 if (ERROR_OK
!= retval
)
1051 str9xpec_info
= bank
->driver_priv
;
1053 tap0
= str9xpec_info
->tap
;
1055 /* remove arm core from chain - enter turbo mode */
1056 tap1
= tap0
->next_tap
;
1058 /* things are *WRONG* */
1059 command_print(CMD_CTX
, "**STR9FLASH** (tap1) invalid chain?");
1062 tap2
= tap1
->next_tap
;
1064 /* things are *WRONG* */
1065 command_print(CMD_CTX
, "**STR9FLASH** (tap2) invalid chain?");
1069 /* enable turbo mode - TURBO-PROG-ENABLE */
1070 str9xpec_set_instr(tap2
, 0xD, TAP_IDLE
);
1071 retval
= jtag_execute_queue();
1072 if (retval
!= ERROR_OK
)
1075 /* modify scan chain - str9 core has been removed */
1081 COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command
)
1083 struct jtag_tap
*tap
;
1084 struct str9xpec_flash_controller
*str9xpec_info
= NULL
;
1087 return ERROR_COMMAND_SYNTAX_ERROR
;
1089 struct flash_bank
*bank
;
1090 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1091 if (ERROR_OK
!= retval
)
1094 str9xpec_info
= bank
->driver_priv
;
1095 tap
= str9xpec_info
->tap
;
1100 /* exit turbo mode via RESET */
1101 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IDLE
);
1103 jtag_execute_queue();
1105 /* restore previous scan chain */
1107 tap
->next_tap
->enabled
= 1;
1112 static const struct command_registration str9xpec_config_command_handlers
[] = {
1114 .name
= "enable_turbo",
1116 .handler
= str9xpec_handle_flash_enable_turbo_command
,
1117 .mode
= COMMAND_EXEC
,
1118 .help
= "enable str9xpec turbo mode",
1121 .name
= "disable_turbo",
1123 .handler
= str9xpec_handle_flash_disable_turbo_command
,
1124 .mode
= COMMAND_EXEC
,
1125 .help
= "disable str9xpec turbo mode",
1128 .name
= "options_cmap",
1129 .usage
= "<bank> <bank0 | bank1>",
1130 .handler
= str9xpec_handle_flash_options_cmap_command
,
1131 .mode
= COMMAND_EXEC
,
1132 .help
= "configure str9xpec boot sector",
1135 .name
= "options_lvdthd",
1136 .usage
= "<bank> <2.4v | 2.7v>",
1137 .handler
= str9xpec_handle_flash_options_lvdthd_command
,
1138 .mode
= COMMAND_EXEC
,
1139 .help
= "configure str9xpec lvd threshold",
1142 .name
= "options_lvdsel",
1143 .usage
= "<bank> <vdd | vdd_vddq>",
1144 .handler
= str9xpec_handle_flash_options_lvdsel_command
,
1145 .mode
= COMMAND_EXEC
,
1146 .help
= "configure str9xpec lvd selection",
1149 .name
= "options_lvdwarn",
1150 .usage
= "<bank> <vdd | vdd_vddq>",
1151 .handler
= str9xpec_handle_flash_options_lvdwarn_command
,
1152 .mode
= COMMAND_EXEC
,
1153 .help
= "configure str9xpec lvd warning",
1156 .name
= "options_read",
1158 .handler
= str9xpec_handle_flash_options_read_command
,
1159 .mode
= COMMAND_EXEC
,
1160 .help
= "read str9xpec options",
1163 .name
= "options_write",
1165 .handler
= str9xpec_handle_flash_options_write_command
,
1166 .mode
= COMMAND_EXEC
,
1167 .help
= "write str9xpec options",
1172 .handler
= str9xpec_handle_flash_lock_command
,
1173 .mode
= COMMAND_EXEC
,
1174 .help
= "lock str9xpec device",
1179 .handler
= str9xpec_handle_flash_unlock_command
,
1180 .mode
= COMMAND_EXEC
,
1181 .help
= "unlock str9xpec device",
1185 .handler
= str9xpec_handle_part_id_command
,
1186 .mode
= COMMAND_EXEC
,
1187 .help
= "print part id of str9xpec flash bank <num>",
1189 COMMAND_REGISTRATION_DONE
1192 static const struct command_registration str9xpec_command_handlers
[] = {
1195 .mode
= COMMAND_ANY
,
1196 .help
= "str9xpec flash command group",
1198 .chain
= str9xpec_config_command_handlers
,
1200 COMMAND_REGISTRATION_DONE
1203 struct flash_driver str9xpec_flash
= {
1205 .commands
= str9xpec_command_handlers
,
1206 .flash_bank_command
= str9xpec_flash_bank_command
,
1207 .erase
= str9xpec_erase
,
1208 .protect
= str9xpec_protect
,
1209 .write
= str9xpec_write
,
1210 .read
= default_flash_read
,
1211 .probe
= str9xpec_probe
,
1212 .auto_probe
= str9xpec_probe
,
1213 .erase_check
= str9xpec_erase_check
,
1214 .protect_check
= str9xpec_protect_check
,
1215 .info
= get_str9xpec_info
,