Added s19 to (fast_)load_image documentation to match the online help.
[openocd/openocdswd.git] / src / flash / nor / str9xpec.c
blobc06e6d163dd707c1c9db3e259a1f54712fe0f248
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
7 * *
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. *
12 * *
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. *
17 * *
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 ***************************************************************************/
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
27 #include "imp.h"
28 #include <target/arm7_9_common.h>
31 /* ISC commands */
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
38 #define ISC_NOOP 0x10
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
45 #define ISC_READ 0x50
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
74 struct jtag_tap *tap;
75 uint32_t *sector_bits;
76 int chain_pos;
77 int isc_enable;
78 uint8_t options[8];
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)
87 if (tap == NULL) {
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);
97 field.out_value = t;
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);
103 free(t);
106 return ERROR_OK;
109 static uint8_t str9xpec_isc_status(struct jtag_tap *tap)
111 struct scan_field field;
112 uint8_t status;
114 if (str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE) != ERROR_OK)
115 return ISC_STATUS_ERROR;
117 field.num_bits = 8;
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");
130 return status;
133 static int str9xpec_isc_enable(struct flash_bank *bank)
135 uint8_t status;
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)
142 return ERROR_OK;
144 /* enter isc mode */
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");
157 return ERROR_OK;
160 static int str9xpec_isc_disable(struct flash_bank *bank)
162 uint8_t status;
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)
169 return ERROR_OK;
171 if (str9xpec_set_instr(tap, ISC_DISABLE, TAP_IDLE) != ERROR_OK)
172 return ERROR_TARGET_INVALID;
174 /* delay to handle aborts */
175 jtag_add_sleep(50);
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");
186 return ERROR_OK;
189 static int str9xpec_read_config(struct flash_bank *bank)
191 struct scan_field field;
192 uint8_t status;
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);
204 field.num_bits = 64;
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);
214 return status;
217 static int str9xpec_build_block_list(struct flash_bank *bank)
219 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
221 int i;
222 int num_sectors;
223 int b0_sectors = 0, b1_sectors = 0;
224 uint32_t offset = 0;
225 int b1_size = 0x2000;
227 switch (bank->size)
229 case (256 * 1024):
230 b0_sectors = 4;
231 break;
232 case (512 * 1024):
233 b0_sectors = 8;
234 break;
235 case (1024 * 1024):
236 b0_sectors = 16;
237 break;
238 case (2048 * 1024):
239 b0_sectors = 32;
240 break;
241 case (128 * 1024):
242 b1_size = 0x4000;
243 b1_sectors = 8;
244 break;
245 case (32 * 1024):
246 b1_sectors = 4;
247 break;
248 default:
249 LOG_ERROR("BUG: unknown bank->size encountered");
250 exit(-1);
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);
259 num_sectors = 0;
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;
281 return ERROR_OK;
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;
293 if (CMD_ARGC < 6)
295 LOG_WARNING("incomplete flash_bank str9x configuration");
296 return ERROR_FLASH_BANK_INVALID;
299 str9xpec_info = malloc(sizeof(struct str9xpec_flash_controller));
300 bank->driver_priv = str9xpec_info;
302 /* REVISIT verify that the jtag position of flash controller is
303 * right after *THIS* core, which must be a STR9xx core ...
305 armv4_5 = bank->target->arch_info;
306 arm7_9 = armv4_5->arch_info;
307 jtag_info = &arm7_9->jtag_info;
309 /* The core is the next tap after the flash controller in the chain */
310 str9xpec_info->tap = jtag_tap_by_position(jtag_info->tap->abs_chain_position - 1);
311 str9xpec_info->isc_enable = 0;
313 str9xpec_build_block_list(bank);
315 /* clear option byte register */
316 buf_set_u32(str9xpec_info->options, 0, 64, 0);
318 return ERROR_OK;
321 static int str9xpec_blank_check(struct flash_bank *bank, int first, int last)
323 struct scan_field field;
324 uint8_t status;
325 struct jtag_tap *tap;
326 int i;
327 uint8_t *buffer = NULL;
329 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
331 tap = str9xpec_info->tap;
333 if (!str9xpec_info->isc_enable) {
334 str9xpec_isc_enable(bank);
337 if (!str9xpec_info->isc_enable) {
338 return ERROR_FLASH_OPERATION_FAILED;
341 buffer = calloc(DIV_ROUND_UP(64, 8), 1);
343 LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first, last);
345 for (i = first; i <= last; i++) {
346 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
349 /* execute ISC_BLANK_CHECK command */
350 str9xpec_set_instr(tap, ISC_BLANK_CHECK, TAP_IRPAUSE);
352 field.num_bits = 64;
353 field.out_value = buffer;
354 field.in_value = NULL;
356 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
357 jtag_add_sleep(40000);
359 /* read blank check result */
360 field.num_bits = 64;
361 field.out_value = NULL;
362 field.in_value = buffer;
364 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
365 jtag_execute_queue();
367 status = str9xpec_isc_status(tap);
369 for (i = first; i <= last; i++)
371 if (buf_get_u32(buffer, str9xpec_info->sector_bits[i], 1))
372 bank->sectors[i].is_erased = 0;
373 else
374 bank->sectors[i].is_erased = 1;
377 free(buffer);
379 str9xpec_isc_disable(bank);
381 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
382 return ERROR_FLASH_OPERATION_FAILED;
383 return ERROR_OK;
386 static int str9xpec_protect_check(struct flash_bank *bank)
388 uint8_t status;
389 int i;
391 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
393 status = str9xpec_read_config(bank);
395 for (i = 0; i < bank->num_sectors; i++)
397 if (buf_get_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1))
398 bank->sectors[i].is_protected = 1;
399 else
400 bank->sectors[i].is_protected = 0;
403 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
404 return ERROR_FLASH_OPERATION_FAILED;
405 return ERROR_OK;
408 static int str9xpec_erase_area(struct flash_bank *bank, int first, int last)
410 struct scan_field field;
411 uint8_t status;
412 struct jtag_tap *tap;
413 int i;
414 uint8_t *buffer = NULL;
416 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
418 tap = str9xpec_info->tap;
420 if (!str9xpec_info->isc_enable) {
421 str9xpec_isc_enable(bank);
424 if (!str9xpec_info->isc_enable) {
425 return ISC_STATUS_ERROR;
428 buffer = calloc(DIV_ROUND_UP(64, 8), 1);
430 LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first, last);
432 /* last bank: 0xFF signals a full erase (unlock complete device) */
433 /* last bank: 0xFE signals a option byte erase */
434 if (last == 0xFF)
436 for (i = 0; i < 64; i++) {
437 buf_set_u32(buffer, i, 1, 1);
440 else if (last == 0xFE)
442 buf_set_u32(buffer, 49, 1, 1);
444 else
446 for (i = first; i <= last; i++) {
447 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
451 LOG_DEBUG("ISC_ERASE");
453 /* execute ISC_ERASE command */
454 str9xpec_set_instr(tap, ISC_ERASE, TAP_IRPAUSE);
456 field.num_bits = 64;
457 field.out_value = buffer;
458 field.in_value = NULL;
460 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
461 jtag_execute_queue();
463 jtag_add_sleep(10);
465 /* wait for erase completion */
466 while (!((status = str9xpec_isc_status(tap)) & ISC_STATUS_BUSY)) {
467 alive_sleep(1);
470 free(buffer);
472 str9xpec_isc_disable(bank);
474 return status;
477 static int str9xpec_erase(struct flash_bank *bank, int first, int last)
479 int status;
481 status = str9xpec_erase_area(bank, first, last);
483 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
484 return ERROR_FLASH_OPERATION_FAILED;
486 return ERROR_OK;
489 static int str9xpec_lock_device(struct flash_bank *bank)
491 struct scan_field field;
492 uint8_t status;
493 struct jtag_tap *tap;
494 struct str9xpec_flash_controller *str9xpec_info = NULL;
496 str9xpec_info = bank->driver_priv;
497 tap = str9xpec_info->tap;
499 if (!str9xpec_info->isc_enable) {
500 str9xpec_isc_enable(bank);
503 if (!str9xpec_info->isc_enable) {
504 return ISC_STATUS_ERROR;
507 /* set security address */
508 str9xpec_set_address(bank, 0x80);
510 /* execute ISC_PROGRAM command */
511 str9xpec_set_instr(tap, ISC_PROGRAM_SECURITY, TAP_IDLE);
513 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
515 do {
516 field.num_bits = 8;
517 field.out_value = NULL;
518 field.in_value = &status;
520 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
521 jtag_execute_queue();
523 } while (!(status & ISC_STATUS_BUSY));
525 str9xpec_isc_disable(bank);
527 return status;
530 static int str9xpec_unlock_device(struct flash_bank *bank)
532 uint8_t status;
534 status = str9xpec_erase_area(bank, 0, 255);
536 return status;
539 static int str9xpec_protect(struct flash_bank *bank, int set, int first, int last)
541 uint8_t status;
542 int i;
544 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
546 status = str9xpec_read_config(bank);
548 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
549 return ERROR_FLASH_OPERATION_FAILED;
551 LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first, last);
553 /* last bank: 0xFF signals a full device protect */
554 if (last == 0xFF)
556 if (set)
558 status = str9xpec_lock_device(bank);
560 else
562 /* perform full erase to unlock device */
563 status = str9xpec_unlock_device(bank);
566 else
568 for (i = first; i <= last; i++)
570 if (set)
571 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 1);
572 else
573 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 0);
576 status = str9xpec_write_options(bank);
579 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
580 return ERROR_FLASH_OPERATION_FAILED;
582 return ERROR_OK;
585 static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector)
587 struct jtag_tap *tap;
588 struct scan_field field;
589 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
591 tap = str9xpec_info->tap;
593 /* set flash controller address */
594 str9xpec_set_instr(tap, ISC_ADDRESS_SHIFT, TAP_IRPAUSE);
596 field.num_bits = 8;
597 field.out_value = &sector;
598 field.in_value = NULL;
600 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
602 return ERROR_OK;
605 static int str9xpec_write(struct flash_bank *bank, uint8_t *buffer,
606 uint32_t offset, uint32_t count)
608 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
609 uint32_t dwords_remaining = (count / 8);
610 uint32_t bytes_remaining = (count & 0x00000007);
611 uint32_t bytes_written = 0;
612 uint8_t status;
613 uint32_t check_address = offset;
614 struct jtag_tap *tap;
615 struct scan_field field;
616 uint8_t *scanbuf;
617 int i;
618 int first_sector = 0;
619 int last_sector = 0;
621 tap = str9xpec_info->tap;
623 if (!str9xpec_info->isc_enable) {
624 str9xpec_isc_enable(bank);
627 if (!str9xpec_info->isc_enable) {
628 return ERROR_FLASH_OPERATION_FAILED;
631 if (offset & 0x7)
633 LOG_WARNING("offset 0x%" PRIx32 " breaks required 8-byte alignment", offset);
634 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
637 for (i = 0; i < bank->num_sectors; i++)
639 uint32_t sec_start = bank->sectors[i].offset;
640 uint32_t sec_end = sec_start + bank->sectors[i].size;
642 /* check if destination falls within the current sector */
643 if ((check_address >= sec_start) && (check_address < sec_end))
645 /* check if destination ends in the current sector */
646 if (offset + count < sec_end)
647 check_address = offset + count;
648 else
649 check_address = sec_end;
652 if ((offset >= sec_start) && (offset < sec_end)) {
653 first_sector = i;
656 if ((offset + count >= sec_start) && (offset + count < sec_end)) {
657 last_sector = i;
661 if (check_address != offset + count)
662 return ERROR_FLASH_DST_OUT_OF_BANK;
664 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
666 scanbuf = calloc(DIV_ROUND_UP(64, 8), 1);
668 LOG_DEBUG("ISC_PROGRAM");
670 for (i = first_sector; i <= last_sector; i++)
672 str9xpec_set_address(bank, str9xpec_info->sector_bits[i]);
674 dwords_remaining = dwords_remaining < (bank->sectors[i].size/8)
675 ? dwords_remaining : (bank->sectors[i].size/8);
677 while (dwords_remaining > 0)
679 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
681 field.num_bits = 64;
682 field.out_value = (buffer + bytes_written);
683 field.in_value = NULL;
685 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
687 /* small delay before polling */
688 jtag_add_sleep(50);
690 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
692 do {
693 field.num_bits = 8;
694 field.out_value = NULL;
695 field.in_value = scanbuf;
697 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
698 jtag_execute_queue();
700 status = buf_get_u32(scanbuf, 0, 8);
702 } while (!(status & ISC_STATUS_BUSY));
704 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
705 return ERROR_FLASH_OPERATION_FAILED;
707 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
708 return ERROR_FLASH_OPERATION_FAILED; */
710 dwords_remaining--;
711 bytes_written += 8;
715 if (bytes_remaining)
717 uint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
718 i = 0;
720 while (bytes_remaining > 0)
722 last_dword[i++] = *(buffer + bytes_written);
723 bytes_remaining--;
724 bytes_written++;
727 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
729 field.num_bits = 64;
730 field.out_value = last_dword;
731 field.in_value = NULL;
733 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
735 /* small delay before polling */
736 jtag_add_sleep(50);
738 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
740 do {
741 field.num_bits = 8;
742 field.out_value = NULL;
743 field.in_value = scanbuf;
745 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
746 jtag_execute_queue();
748 status = buf_get_u32(scanbuf, 0, 8);
750 } while (!(status & ISC_STATUS_BUSY));
752 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
753 return ERROR_FLASH_OPERATION_FAILED;
755 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
756 return ERROR_FLASH_OPERATION_FAILED; */
759 free(scanbuf);
761 str9xpec_isc_disable(bank);
763 return ERROR_OK;
766 static int str9xpec_probe(struct flash_bank *bank)
768 return ERROR_OK;
771 COMMAND_HANDLER(str9xpec_handle_part_id_command)
773 struct scan_field field;
774 uint8_t *buffer = NULL;
775 struct jtag_tap *tap;
776 uint32_t idcode;
777 struct str9xpec_flash_controller *str9xpec_info = NULL;
779 if (CMD_ARGC < 1)
780 return ERROR_COMMAND_SYNTAX_ERROR;
782 struct flash_bank *bank;
783 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
784 if (ERROR_OK != retval)
785 return retval;
787 str9xpec_info = bank->driver_priv;
788 tap = str9xpec_info->tap;
790 buffer = calloc(DIV_ROUND_UP(32, 8), 1);
792 str9xpec_set_instr(tap, ISC_IDCODE, TAP_IRPAUSE);
794 field.num_bits = 32;
795 field.out_value = NULL;
796 field.in_value = buffer;
798 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
799 jtag_execute_queue();
801 idcode = buf_get_u32(buffer, 0, 32);
803 command_print(CMD_CTX, "str9xpec part id: 0x%8.8" PRIx32 "", idcode);
805 free(buffer);
807 return ERROR_OK;
810 static int str9xpec_erase_check(struct flash_bank *bank)
812 return str9xpec_blank_check(bank, 0, bank->num_sectors - 1);
815 static int get_str9xpec_info(struct flash_bank *bank, char *buf, int buf_size)
817 snprintf(buf, buf_size, "str9xpec flash driver info");
818 return ERROR_OK;
821 COMMAND_HANDLER(str9xpec_handle_flash_options_read_command)
823 uint8_t status;
824 struct str9xpec_flash_controller *str9xpec_info = NULL;
826 if (CMD_ARGC < 1)
828 command_print(CMD_CTX, "str9xpec options_read <bank>");
829 return ERROR_OK;
832 struct flash_bank *bank;
833 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
834 if (ERROR_OK != retval)
835 return retval;
837 str9xpec_info = bank->driver_priv;
839 status = str9xpec_read_config(bank);
841 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
842 return ERROR_FLASH_OPERATION_FAILED;
844 /* boot bank */
845 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1))
846 command_print(CMD_CTX, "CS Map: bank1");
847 else
848 command_print(CMD_CTX, "CS Map: bank0");
850 /* OTP lock */
851 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1))
852 command_print(CMD_CTX, "OTP Lock: OTP Locked");
853 else
854 command_print(CMD_CTX, "OTP Lock: OTP Unlocked");
856 /* LVD Threshold */
857 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1))
858 command_print(CMD_CTX, "LVD Threshold: 2.7v");
859 else
860 command_print(CMD_CTX, "LVD Threshold: 2.4v");
862 /* LVD reset warning */
863 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1))
864 command_print(CMD_CTX, "LVD Reset Warning: VDD or VDDQ Inputs");
865 else
866 command_print(CMD_CTX, "LVD Reset Warning: VDD Input Only");
868 /* LVD reset select */
869 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1))
870 command_print(CMD_CTX, "LVD Reset Selection: VDD or VDDQ Inputs");
871 else
872 command_print(CMD_CTX, "LVD Reset Selection: VDD Input Only");
874 return ERROR_OK;
877 static int str9xpec_write_options(struct flash_bank *bank)
879 struct scan_field field;
880 uint8_t status;
881 struct jtag_tap *tap;
882 struct str9xpec_flash_controller *str9xpec_info = NULL;
884 str9xpec_info = bank->driver_priv;
885 tap = str9xpec_info->tap;
887 /* erase config options first */
888 status = str9xpec_erase_area(bank, 0xFE, 0xFE);
890 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
891 return status;
893 if (!str9xpec_info->isc_enable) {
894 str9xpec_isc_enable(bank);
897 if (!str9xpec_info->isc_enable) {
898 return ISC_STATUS_ERROR;
901 /* according to data 64th bit has to be set */
902 buf_set_u32(str9xpec_info->options, 63, 1, 1);
904 /* set option byte address */
905 str9xpec_set_address(bank, 0x50);
907 /* execute ISC_PROGRAM command */
908 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
910 field.num_bits = 64;
911 field.out_value = str9xpec_info->options;
912 field.in_value = NULL;
914 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
916 /* small delay before polling */
917 jtag_add_sleep(50);
919 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
921 do {
922 field.num_bits = 8;
923 field.out_value = NULL;
924 field.in_value = &status;
926 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
927 jtag_execute_queue();
929 } while (!(status & ISC_STATUS_BUSY));
931 str9xpec_isc_disable(bank);
933 return status;
936 COMMAND_HANDLER(str9xpec_handle_flash_options_write_command)
938 uint8_t status;
940 if (CMD_ARGC < 1)
942 command_print(CMD_CTX, "str9xpec options_write <bank>");
943 return ERROR_OK;
946 struct flash_bank *bank;
947 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
948 if (ERROR_OK != retval)
949 return retval;
951 status = str9xpec_write_options(bank);
953 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
954 return ERROR_FLASH_OPERATION_FAILED;
956 command_print(CMD_CTX, "str9xpec write options complete.\n"
957 "INFO: a reset or power cycle is required "
958 "for the new settings to take effect.");
960 return ERROR_OK;
963 COMMAND_HANDLER(str9xpec_handle_flash_options_cmap_command)
965 struct str9xpec_flash_controller *str9xpec_info = NULL;
967 if (CMD_ARGC < 2)
969 command_print(CMD_CTX, "str9xpec options_cmap <bank> <bank0 | bank1>");
970 return ERROR_OK;
973 struct flash_bank *bank;
974 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
975 if (ERROR_OK != retval)
976 return retval;
978 str9xpec_info = bank->driver_priv;
980 if (strcmp(CMD_ARGV[1], "bank1") == 0)
982 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 1);
984 else
986 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0);
989 return ERROR_OK;
992 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdthd_command)
994 struct str9xpec_flash_controller *str9xpec_info = NULL;
996 if (CMD_ARGC < 2)
998 command_print(CMD_CTX, "str9xpec options_lvdthd <bank> <2.4v | 2.7v>");
999 return ERROR_OK;
1002 struct flash_bank *bank;
1003 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1004 if (ERROR_OK != retval)
1005 return retval;
1007 str9xpec_info = bank->driver_priv;
1009 if (strcmp(CMD_ARGV[1], "2.7v") == 0)
1011 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 1);
1013 else
1015 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0);
1018 return ERROR_OK;
1021 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdsel_command)
1023 struct str9xpec_flash_controller *str9xpec_info = NULL;
1025 if (CMD_ARGC < 2)
1027 command_print(CMD_CTX, "str9xpec options_lvdsel <bank> <vdd | vdd_vddq>");
1028 return ERROR_OK;
1031 struct flash_bank *bank;
1032 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1033 if (ERROR_OK != retval)
1034 return retval;
1036 str9xpec_info = bank->driver_priv;
1038 if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0)
1040 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 1);
1042 else
1044 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0);
1047 return ERROR_OK;
1050 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdwarn_command)
1052 struct str9xpec_flash_controller *str9xpec_info = NULL;
1054 if (CMD_ARGC < 2)
1056 command_print(CMD_CTX, "str9xpec options_lvdwarn <bank> <vdd | vdd_vddq>");
1057 return ERROR_OK;
1060 struct flash_bank *bank;
1061 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1062 if (ERROR_OK != retval)
1063 return retval;
1065 str9xpec_info = bank->driver_priv;
1067 if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0)
1069 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 1);
1071 else
1073 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0);
1076 return ERROR_OK;
1079 COMMAND_HANDLER(str9xpec_handle_flash_lock_command)
1081 uint8_t status;
1083 if (CMD_ARGC < 1)
1085 command_print(CMD_CTX, "str9xpec lock <bank>");
1086 return ERROR_OK;
1089 struct flash_bank *bank;
1090 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1091 if (ERROR_OK != retval)
1092 return retval;
1094 status = str9xpec_lock_device(bank);
1096 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1097 return ERROR_FLASH_OPERATION_FAILED;
1099 return ERROR_OK;
1102 COMMAND_HANDLER(str9xpec_handle_flash_unlock_command)
1104 uint8_t status;
1106 if (CMD_ARGC < 1)
1108 command_print(CMD_CTX, "str9xpec unlock <bank>");
1109 return ERROR_OK;
1112 struct flash_bank *bank;
1113 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1114 if (ERROR_OK != retval)
1115 return retval;
1117 status = str9xpec_unlock_device(bank);
1119 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1120 return ERROR_FLASH_OPERATION_FAILED;
1122 command_print(CMD_CTX, "str9xpec unlocked.\n"
1123 "INFO: a reset or power cycle is required "
1124 "for the new settings to take effect.");
1126 return ERROR_OK;
1129 COMMAND_HANDLER(str9xpec_handle_flash_enable_turbo_command)
1131 struct jtag_tap *tap0;
1132 struct jtag_tap *tap1;
1133 struct jtag_tap *tap2;
1134 struct str9xpec_flash_controller *str9xpec_info = NULL;
1136 if (CMD_ARGC < 1)
1138 command_print(CMD_CTX, "str9xpec enable_turbo <bank>");
1139 return ERROR_OK;
1142 struct flash_bank *bank;
1143 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1144 if (ERROR_OK != retval)
1145 return retval;
1147 str9xpec_info = bank->driver_priv;
1149 tap0 = str9xpec_info->tap;
1151 /* remove arm core from chain - enter turbo mode */
1152 tap1 = tap0->next_tap;
1153 if (tap1 == NULL)
1155 /* things are *WRONG* */
1156 command_print(CMD_CTX,"**STR9FLASH** (tap1) invalid chain?");
1157 return ERROR_OK;
1159 tap2 = tap1->next_tap;
1160 if (tap2 == NULL)
1162 /* things are *WRONG* */
1163 command_print(CMD_CTX,"**STR9FLASH** (tap2) invalid chain?");
1164 return ERROR_OK;
1167 /* enable turbo mode - TURBO-PROG-ENABLE */
1168 str9xpec_set_instr(tap2, 0xD, TAP_IDLE);
1169 if ((retval = jtag_execute_queue()) != ERROR_OK)
1170 return retval;
1172 /* modify scan chain - str9 core has been removed */
1173 tap1->enabled = 0;
1175 return ERROR_OK;
1178 COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command)
1180 struct jtag_tap *tap;
1181 struct str9xpec_flash_controller *str9xpec_info = NULL;
1183 if (CMD_ARGC < 1)
1185 command_print(CMD_CTX, "str9xpec disable_turbo <bank>");
1186 return ERROR_OK;
1189 struct flash_bank *bank;
1190 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1191 if (ERROR_OK != retval)
1192 return retval;
1194 str9xpec_info = bank->driver_priv;
1195 tap = str9xpec_info->tap;
1197 if (tap == NULL)
1198 return ERROR_FAIL;
1200 /* exit turbo mode via RESET */
1201 str9xpec_set_instr(tap, ISC_NOOP, TAP_IDLE);
1202 jtag_add_tlr();
1203 jtag_execute_queue();
1205 /* restore previous scan chain */
1206 if (tap->next_tap) {
1207 tap->next_tap->enabled = 1;
1210 return ERROR_OK;
1213 static const struct command_registration str9xpec_config_command_handlers[] = {
1215 .name = "enable_turbo",
1216 .handler = str9xpec_handle_flash_enable_turbo_command,
1217 .mode = COMMAND_EXEC,
1218 .help = "enable str9xpec turbo mode",
1221 .name = "disable_turbo",
1222 .handler = str9xpec_handle_flash_disable_turbo_command,
1223 .mode = COMMAND_EXEC,
1224 .help = "disable str9xpec turbo mode",
1227 .name = "options_cmap",
1228 .handler = str9xpec_handle_flash_options_cmap_command,
1229 .mode = COMMAND_EXEC,
1230 .help = "configure str9xpec boot sector",
1233 .name = "options_lvdthd",
1234 .handler = str9xpec_handle_flash_options_lvdthd_command,
1235 .mode = COMMAND_EXEC,
1236 .help = "configure str9xpec lvd threshold",
1239 .name = "options_lvdsel",
1240 .handler = str9xpec_handle_flash_options_lvdsel_command,
1241 .mode = COMMAND_EXEC,
1242 .help = "configure str9xpec lvd selection",
1245 .name = "options_lvdwarn",
1246 .handler = str9xpec_handle_flash_options_lvdwarn_command,
1247 .mode = COMMAND_EXEC,
1248 .help = "configure str9xpec lvd warning",
1251 .name = "options_read",
1252 .handler = str9xpec_handle_flash_options_read_command,
1253 .mode = COMMAND_EXEC,
1254 .help = "read str9xpec options",
1257 .name = "options_write",
1258 .handler = str9xpec_handle_flash_options_write_command,
1259 .mode = COMMAND_EXEC,
1260 .help = "write str9xpec options",
1263 .name = "lock",
1264 .handler = str9xpec_handle_flash_lock_command,
1265 .mode = COMMAND_EXEC,
1266 .help = "lock str9xpec device",
1269 .name = "unlock",
1270 .handler = str9xpec_handle_flash_unlock_command,
1271 .mode = COMMAND_EXEC,
1272 .help = "unlock str9xpec device",
1275 .name = "part_id",
1276 .handler = str9xpec_handle_part_id_command,
1277 .mode = COMMAND_EXEC,
1278 .help = "print part id of str9xpec flash bank <num>",
1280 COMMAND_REGISTRATION_DONE
1283 static const struct command_registration str9xpec_command_handlers[] = {
1285 .name = "str9xpec",
1286 .mode = COMMAND_ANY,
1287 .help = "str9xpec flash command group",
1288 .chain = str9xpec_config_command_handlers,
1290 COMMAND_REGISTRATION_DONE
1293 struct flash_driver str9xpec_flash = {
1294 .name = "str9xpec",
1295 .commands = str9xpec_command_handlers,
1296 .flash_bank_command = str9xpec_flash_bank_command,
1297 .erase = str9xpec_erase,
1298 .protect = str9xpec_protect,
1299 .write = str9xpec_write,
1300 .read = default_flash_read,
1301 .probe = str9xpec_probe,
1302 .auto_probe = str9xpec_probe,
1303 .erase_check = str9xpec_erase_check,
1304 .protect_check = str9xpec_protect_check,
1305 .info = get_str9xpec_info,