Remove FSF address from GPL notices
[openocd.git] / src / flash / nor / str9xpec.c
blobeb391e8fbffbea9915ead0983a13176e9057d5d6
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, see <http://www.gnu.org/licenses/>. *
20 ***************************************************************************/
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
26 #include "imp.h"
27 #include <target/arm7_9_common.h>
29 /* ISC commands */
31 #define ISC_IDCODE 0xFE
32 #define ISC_MFG_READ 0x4C
33 #define ISC_CONFIGURATION 0x07
34 #define ISC_ENABLE 0x0C
35 #define ISC_DISABLE 0x0F
36 #define ISC_NOOP 0x10
37 #define ISC_ADDRESS_SHIFT 0x11
38 #define ISC_CLR_STATUS 0x13
39 #define ISC_PROGRAM 0x20
40 #define ISC_PROGRAM_SECURITY 0x22
41 #define ISC_PROGRAM_UC 0x23
42 #define ISC_ERASE 0x30
43 #define ISC_READ 0x50
44 #define ISC_BLANK_CHECK 0x60
46 /* ISC_DEFAULT bit definitions */
48 #define ISC_STATUS_SECURITY 0x40
49 #define ISC_STATUS_INT_ERROR 0x30
50 #define ISC_STATUS_MODE 0x08
51 #define ISC_STATUS_BUSY 0x04
52 #define ISC_STATUS_ERROR 0x03
54 /* Option bytes definitions */
56 #define STR9XPEC_OPT_CSMAPBIT 48
57 #define STR9XPEC_OPT_LVDTHRESBIT 49
58 #define STR9XPEC_OPT_LVDSELBIT 50
59 #define STR9XPEC_OPT_LVDWARNBIT 51
60 #define STR9XPEC_OPT_OTPBIT 63
62 enum str9xpec_status_codes {
63 STR9XPEC_INVALID_COMMAND = 1,
64 STR9XPEC_ISC_SUCCESS = 2,
65 STR9XPEC_ISC_DISABLED = 3,
66 STR9XPEC_ISC_INTFAIL = 32,
69 struct str9xpec_flash_controller {
70 struct jtag_tap *tap;
71 uint32_t *sector_bits;
72 int chain_pos;
73 int isc_enable;
74 uint8_t options[8];
77 static int str9xpec_erase_area(struct flash_bank *bank, int first, int last);
78 static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector);
79 static int str9xpec_write_options(struct flash_bank *bank);
81 static int str9xpec_set_instr(struct jtag_tap *tap, uint32_t new_instr, tap_state_t end_state)
83 if (tap == NULL)
84 return ERROR_TARGET_INVALID;
86 if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) {
87 struct scan_field field;
89 field.num_bits = tap->ir_length;
90 void *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);
91 field.out_value = t;
92 buf_set_u32(t, 0, field.num_bits, new_instr);
93 field.in_value = NULL;
95 jtag_add_ir_scan(tap, &field, end_state);
97 free(t);
100 return ERROR_OK;
103 static uint8_t str9xpec_isc_status(struct jtag_tap *tap)
105 struct scan_field field;
106 uint8_t status;
108 if (str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE) != ERROR_OK)
109 return ISC_STATUS_ERROR;
111 field.num_bits = 8;
112 field.out_value = NULL;
113 field.in_value = &status;
116 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
117 jtag_execute_queue();
119 LOG_DEBUG("status: 0x%2.2x", status);
121 if (status & ISC_STATUS_SECURITY)
122 LOG_INFO("Device Security Bit Set");
124 return status;
127 static int str9xpec_isc_enable(struct flash_bank *bank)
129 uint8_t status;
130 struct jtag_tap *tap;
131 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
133 tap = str9xpec_info->tap;
135 if (str9xpec_info->isc_enable)
136 return ERROR_OK;
138 /* enter isc mode */
139 if (str9xpec_set_instr(tap, ISC_ENABLE, TAP_IDLE) != ERROR_OK)
140 return ERROR_TARGET_INVALID;
142 /* check ISC status */
143 status = str9xpec_isc_status(tap);
144 if (status & ISC_STATUS_MODE) {
145 /* we have entered isc mode */
146 str9xpec_info->isc_enable = 1;
147 LOG_DEBUG("ISC_MODE Enabled");
150 return ERROR_OK;
153 static int str9xpec_isc_disable(struct flash_bank *bank)
155 uint8_t status;
156 struct jtag_tap *tap;
157 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
159 tap = str9xpec_info->tap;
161 if (!str9xpec_info->isc_enable)
162 return ERROR_OK;
164 if (str9xpec_set_instr(tap, ISC_DISABLE, TAP_IDLE) != ERROR_OK)
165 return ERROR_TARGET_INVALID;
167 /* delay to handle aborts */
168 jtag_add_sleep(50);
170 /* check ISC status */
171 status = str9xpec_isc_status(tap);
172 if (!(status & ISC_STATUS_MODE)) {
173 /* we have left isc mode */
174 str9xpec_info->isc_enable = 0;
175 LOG_DEBUG("ISC_MODE Disabled");
178 return ERROR_OK;
181 static int str9xpec_read_config(struct flash_bank *bank)
183 struct scan_field field;
184 uint8_t status;
185 struct jtag_tap *tap;
187 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
189 tap = str9xpec_info->tap;
191 LOG_DEBUG("ISC_CONFIGURATION");
193 /* execute ISC_CONFIGURATION command */
194 str9xpec_set_instr(tap, ISC_CONFIGURATION, TAP_IRPAUSE);
196 field.num_bits = 64;
197 field.out_value = NULL;
198 field.in_value = str9xpec_info->options;
200 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
201 jtag_execute_queue();
203 status = str9xpec_isc_status(tap);
205 return status;
208 static int str9xpec_build_block_list(struct flash_bank *bank)
210 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
212 int i;
213 int num_sectors;
214 int b0_sectors = 0, b1_sectors = 0;
215 uint32_t offset = 0;
216 int b1_size = 0x2000;
218 switch (bank->size) {
219 case (256 * 1024):
220 b0_sectors = 4;
221 break;
222 case (512 * 1024):
223 b0_sectors = 8;
224 break;
225 case (1024 * 1024):
226 b0_sectors = 16;
227 break;
228 case (2048 * 1024):
229 b0_sectors = 32;
230 break;
231 case (128 * 1024):
232 b1_size = 0x4000;
233 b1_sectors = 8;
234 break;
235 case (32 * 1024):
236 b1_sectors = 4;
237 break;
238 default:
239 LOG_ERROR("BUG: unknown bank->size encountered");
240 exit(-1);
243 num_sectors = b0_sectors + b1_sectors;
245 bank->num_sectors = num_sectors;
246 bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);
247 str9xpec_info->sector_bits = malloc(sizeof(uint32_t) * num_sectors);
249 num_sectors = 0;
251 for (i = 0; i < b0_sectors; i++) {
252 bank->sectors[num_sectors].offset = offset;
253 bank->sectors[num_sectors].size = 0x10000;
254 offset += bank->sectors[i].size;
255 bank->sectors[num_sectors].is_erased = -1;
256 bank->sectors[num_sectors].is_protected = 1;
257 str9xpec_info->sector_bits[num_sectors++] = i;
260 for (i = 0; i < b1_sectors; i++) {
261 bank->sectors[num_sectors].offset = offset;
262 bank->sectors[num_sectors].size = b1_size;
263 offset += bank->sectors[i].size;
264 bank->sectors[num_sectors].is_erased = -1;
265 bank->sectors[num_sectors].is_protected = 1;
266 str9xpec_info->sector_bits[num_sectors++] = i + 32;
269 return ERROR_OK;
272 /* flash bank str9x <base> <size> 0 0 <target#>
274 FLASH_BANK_COMMAND_HANDLER(str9xpec_flash_bank_command)
276 struct str9xpec_flash_controller *str9xpec_info;
277 struct arm *arm = NULL;
278 struct arm7_9_common *arm7_9 = NULL;
279 struct arm_jtag *jtag_info = NULL;
281 if (CMD_ARGC < 6)
282 return ERROR_COMMAND_SYNTAX_ERROR;
284 str9xpec_info = malloc(sizeof(struct str9xpec_flash_controller));
285 bank->driver_priv = str9xpec_info;
287 /* REVISIT verify that the jtag position of flash controller is
288 * right after *THIS* core, which must be a STR9xx core ...
290 arm = bank->target->arch_info;
291 arm7_9 = arm->arch_info;
292 jtag_info = &arm7_9->jtag_info;
294 /* The core is the next tap after the flash controller in the chain */
295 str9xpec_info->tap = jtag_tap_by_position(jtag_info->tap->abs_chain_position - 1);
296 str9xpec_info->isc_enable = 0;
298 str9xpec_build_block_list(bank);
300 /* clear option byte register */
301 buf_set_u32(str9xpec_info->options, 0, 64, 0);
303 return ERROR_OK;
306 static int str9xpec_blank_check(struct flash_bank *bank, int first, int last)
308 struct scan_field field;
309 uint8_t status;
310 struct jtag_tap *tap;
311 int i;
312 uint8_t *buffer = NULL;
314 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
316 tap = str9xpec_info->tap;
318 if (!str9xpec_info->isc_enable)
319 str9xpec_isc_enable(bank);
321 if (!str9xpec_info->isc_enable)
322 return ERROR_FLASH_OPERATION_FAILED;
324 buffer = calloc(DIV_ROUND_UP(64, 8), 1);
326 LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first, last);
328 for (i = first; i <= last; i++)
329 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
331 /* execute ISC_BLANK_CHECK command */
332 str9xpec_set_instr(tap, ISC_BLANK_CHECK, TAP_IRPAUSE);
334 field.num_bits = 64;
335 field.out_value = buffer;
336 field.in_value = NULL;
338 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
339 jtag_add_sleep(40000);
341 /* read blank check result */
342 field.num_bits = 64;
343 field.out_value = NULL;
344 field.in_value = buffer;
346 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
347 jtag_execute_queue();
349 status = str9xpec_isc_status(tap);
351 for (i = first; i <= last; i++) {
352 if (buf_get_u32(buffer, str9xpec_info->sector_bits[i], 1))
353 bank->sectors[i].is_erased = 0;
354 else
355 bank->sectors[i].is_erased = 1;
358 free(buffer);
360 str9xpec_isc_disable(bank);
362 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
363 return ERROR_FLASH_OPERATION_FAILED;
364 return ERROR_OK;
367 static int str9xpec_protect_check(struct flash_bank *bank)
369 uint8_t status;
370 int i;
372 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
374 status = str9xpec_read_config(bank);
376 for (i = 0; i < bank->num_sectors; i++) {
377 if (buf_get_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1))
378 bank->sectors[i].is_protected = 1;
379 else
380 bank->sectors[i].is_protected = 0;
383 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
384 return ERROR_FLASH_OPERATION_FAILED;
385 return ERROR_OK;
388 static int str9xpec_erase_area(struct flash_bank *bank, int first, int last)
390 struct scan_field field;
391 uint8_t status;
392 struct jtag_tap *tap;
393 int i;
394 uint8_t *buffer = NULL;
396 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
398 tap = str9xpec_info->tap;
400 if (!str9xpec_info->isc_enable)
401 str9xpec_isc_enable(bank);
403 if (!str9xpec_info->isc_enable)
404 return ISC_STATUS_ERROR;
406 buffer = calloc(DIV_ROUND_UP(64, 8), 1);
408 LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first, last);
410 /* last bank: 0xFF signals a full erase (unlock complete device) */
411 /* last bank: 0xFE signals a option byte erase */
412 if (last == 0xFF) {
413 for (i = 0; i < 64; i++)
414 buf_set_u32(buffer, i, 1, 1);
415 } else if (last == 0xFE)
416 buf_set_u32(buffer, 49, 1, 1);
417 else {
418 for (i = first; i <= last; i++)
419 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
422 LOG_DEBUG("ISC_ERASE");
424 /* execute ISC_ERASE command */
425 str9xpec_set_instr(tap, ISC_ERASE, TAP_IRPAUSE);
427 field.num_bits = 64;
428 field.out_value = buffer;
429 field.in_value = NULL;
431 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
432 jtag_execute_queue();
434 jtag_add_sleep(10);
436 /* wait for erase completion */
437 while (!((status = str9xpec_isc_status(tap)) & ISC_STATUS_BUSY))
438 alive_sleep(1);
440 free(buffer);
442 str9xpec_isc_disable(bank);
444 return status;
447 static int str9xpec_erase(struct flash_bank *bank, int first, int last)
449 int status;
451 status = str9xpec_erase_area(bank, first, last);
453 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
454 return ERROR_FLASH_OPERATION_FAILED;
456 return ERROR_OK;
459 static int str9xpec_lock_device(struct flash_bank *bank)
461 struct scan_field field;
462 uint8_t status;
463 struct jtag_tap *tap;
464 struct str9xpec_flash_controller *str9xpec_info = NULL;
466 str9xpec_info = bank->driver_priv;
467 tap = str9xpec_info->tap;
469 if (!str9xpec_info->isc_enable)
470 str9xpec_isc_enable(bank);
472 if (!str9xpec_info->isc_enable)
473 return ISC_STATUS_ERROR;
475 /* set security address */
476 str9xpec_set_address(bank, 0x80);
478 /* execute ISC_PROGRAM command */
479 str9xpec_set_instr(tap, ISC_PROGRAM_SECURITY, TAP_IDLE);
481 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
483 do {
484 field.num_bits = 8;
485 field.out_value = NULL;
486 field.in_value = &status;
488 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
489 jtag_execute_queue();
491 } while (!(status & ISC_STATUS_BUSY));
493 str9xpec_isc_disable(bank);
495 return status;
498 static int str9xpec_unlock_device(struct flash_bank *bank)
500 uint8_t status;
502 status = str9xpec_erase_area(bank, 0, 255);
504 return status;
507 static int str9xpec_protect(struct flash_bank *bank, int set, int first, int last)
509 uint8_t status;
510 int i;
512 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
514 status = str9xpec_read_config(bank);
516 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
517 return ERROR_FLASH_OPERATION_FAILED;
519 LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first, last);
521 /* last bank: 0xFF signals a full device protect */
522 if (last == 0xFF) {
523 if (set)
524 status = str9xpec_lock_device(bank);
525 else {
526 /* perform full erase to unlock device */
527 status = str9xpec_unlock_device(bank);
529 } else {
530 for (i = first; i <= last; i++) {
531 if (set)
532 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 1);
533 else
534 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 0);
537 status = str9xpec_write_options(bank);
540 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
541 return ERROR_FLASH_OPERATION_FAILED;
543 return ERROR_OK;
546 static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector)
548 struct jtag_tap *tap;
549 struct scan_field field;
550 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
552 tap = str9xpec_info->tap;
554 /* set flash controller address */
555 str9xpec_set_instr(tap, ISC_ADDRESS_SHIFT, TAP_IRPAUSE);
557 field.num_bits = 8;
558 field.out_value = &sector;
559 field.in_value = NULL;
561 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
563 return ERROR_OK;
566 static int str9xpec_write(struct flash_bank *bank, const uint8_t *buffer,
567 uint32_t offset, uint32_t count)
569 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
570 uint32_t dwords_remaining = (count / 8);
571 uint32_t bytes_remaining = (count & 0x00000007);
572 uint32_t bytes_written = 0;
573 uint8_t status;
574 uint32_t check_address = offset;
575 struct jtag_tap *tap;
576 struct scan_field field;
577 uint8_t *scanbuf;
578 int i;
579 int first_sector = 0;
580 int last_sector = 0;
582 tap = str9xpec_info->tap;
584 if (!str9xpec_info->isc_enable)
585 str9xpec_isc_enable(bank);
587 if (!str9xpec_info->isc_enable)
588 return ERROR_FLASH_OPERATION_FAILED;
590 if (offset & 0x7) {
591 LOG_WARNING("offset 0x%" PRIx32 " breaks required 8-byte alignment", offset);
592 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
595 for (i = 0; i < bank->num_sectors; i++) {
596 uint32_t sec_start = bank->sectors[i].offset;
597 uint32_t sec_end = sec_start + bank->sectors[i].size;
599 /* check if destination falls within the current sector */
600 if ((check_address >= sec_start) && (check_address < sec_end)) {
601 /* check if destination ends in the current sector */
602 if (offset + count < sec_end)
603 check_address = offset + count;
604 else
605 check_address = sec_end;
608 if ((offset >= sec_start) && (offset < sec_end))
609 first_sector = i;
611 if ((offset + count >= sec_start) && (offset + count < sec_end))
612 last_sector = i;
615 if (check_address != offset + count)
616 return ERROR_FLASH_DST_OUT_OF_BANK;
618 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
620 scanbuf = calloc(DIV_ROUND_UP(64, 8), 1);
622 LOG_DEBUG("ISC_PROGRAM");
624 for (i = first_sector; i <= last_sector; i++) {
625 str9xpec_set_address(bank, str9xpec_info->sector_bits[i]);
627 dwords_remaining = dwords_remaining < (bank->sectors[i].size/8)
628 ? dwords_remaining : (bank->sectors[i].size/8);
630 while (dwords_remaining > 0) {
631 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
633 field.num_bits = 64;
634 field.out_value = (buffer + bytes_written);
635 field.in_value = NULL;
637 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
639 /* small delay before polling */
640 jtag_add_sleep(50);
642 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
644 do {
645 field.num_bits = 8;
646 field.out_value = NULL;
647 field.in_value = scanbuf;
649 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
650 jtag_execute_queue();
652 status = buf_get_u32(scanbuf, 0, 8);
654 } while (!(status & ISC_STATUS_BUSY));
656 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
657 return ERROR_FLASH_OPERATION_FAILED;
659 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
660 return ERROR_FLASH_OPERATION_FAILED; */
662 dwords_remaining--;
663 bytes_written += 8;
667 if (bytes_remaining) {
668 uint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
670 /* copy the last remaining bytes into the write buffer */
671 memcpy(last_dword, buffer+bytes_written, bytes_remaining);
673 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
675 field.num_bits = 64;
676 field.out_value = last_dword;
677 field.in_value = NULL;
679 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
681 /* small delay before polling */
682 jtag_add_sleep(50);
684 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
686 do {
687 field.num_bits = 8;
688 field.out_value = NULL;
689 field.in_value = scanbuf;
691 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
692 jtag_execute_queue();
694 status = buf_get_u32(scanbuf, 0, 8);
696 } while (!(status & ISC_STATUS_BUSY));
698 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
699 return ERROR_FLASH_OPERATION_FAILED;
701 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
702 return ERROR_FLASH_OPERATION_FAILED; */
705 free(scanbuf);
707 str9xpec_isc_disable(bank);
709 return ERROR_OK;
712 static int str9xpec_probe(struct flash_bank *bank)
714 return ERROR_OK;
717 COMMAND_HANDLER(str9xpec_handle_part_id_command)
719 struct scan_field field;
720 uint8_t *buffer = NULL;
721 struct jtag_tap *tap;
722 uint32_t idcode;
723 struct str9xpec_flash_controller *str9xpec_info = NULL;
725 if (CMD_ARGC < 1)
726 return ERROR_COMMAND_SYNTAX_ERROR;
728 struct flash_bank *bank;
729 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
730 if (ERROR_OK != retval)
731 return retval;
733 str9xpec_info = bank->driver_priv;
734 tap = str9xpec_info->tap;
736 buffer = calloc(DIV_ROUND_UP(32, 8), 1);
738 str9xpec_set_instr(tap, ISC_IDCODE, TAP_IRPAUSE);
740 field.num_bits = 32;
741 field.out_value = NULL;
742 field.in_value = buffer;
744 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
745 jtag_execute_queue();
747 idcode = buf_get_u32(buffer, 0, 32);
749 command_print(CMD_CTX, "str9xpec part id: 0x%8.8" PRIx32 "", idcode);
751 free(buffer);
753 return ERROR_OK;
756 static int str9xpec_erase_check(struct flash_bank *bank)
758 return str9xpec_blank_check(bank, 0, bank->num_sectors - 1);
761 COMMAND_HANDLER(str9xpec_handle_flash_options_read_command)
763 uint8_t status;
764 struct str9xpec_flash_controller *str9xpec_info = NULL;
766 if (CMD_ARGC < 1)
767 return ERROR_COMMAND_SYNTAX_ERROR;
769 struct flash_bank *bank;
770 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
771 if (ERROR_OK != retval)
772 return retval;
774 str9xpec_info = bank->driver_priv;
776 status = str9xpec_read_config(bank);
778 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
779 return ERROR_FLASH_OPERATION_FAILED;
781 /* boot bank */
782 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1))
783 command_print(CMD_CTX, "CS Map: bank1");
784 else
785 command_print(CMD_CTX, "CS Map: bank0");
787 /* OTP lock */
788 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1))
789 command_print(CMD_CTX, "OTP Lock: OTP Locked");
790 else
791 command_print(CMD_CTX, "OTP Lock: OTP Unlocked");
793 /* LVD Threshold */
794 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1))
795 command_print(CMD_CTX, "LVD Threshold: 2.7v");
796 else
797 command_print(CMD_CTX, "LVD Threshold: 2.4v");
799 /* LVD reset warning */
800 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1))
801 command_print(CMD_CTX, "LVD Reset Warning: VDD or VDDQ Inputs");
802 else
803 command_print(CMD_CTX, "LVD Reset Warning: VDD Input Only");
805 /* LVD reset select */
806 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1))
807 command_print(CMD_CTX, "LVD Reset Selection: VDD or VDDQ Inputs");
808 else
809 command_print(CMD_CTX, "LVD Reset Selection: VDD Input Only");
811 return ERROR_OK;
814 static int str9xpec_write_options(struct flash_bank *bank)
816 struct scan_field field;
817 uint8_t status;
818 struct jtag_tap *tap;
819 struct str9xpec_flash_controller *str9xpec_info = NULL;
821 str9xpec_info = bank->driver_priv;
822 tap = str9xpec_info->tap;
824 /* erase config options first */
825 status = str9xpec_erase_area(bank, 0xFE, 0xFE);
827 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
828 return status;
830 if (!str9xpec_info->isc_enable)
831 str9xpec_isc_enable(bank);
833 if (!str9xpec_info->isc_enable)
834 return ISC_STATUS_ERROR;
836 /* according to data 64th bit has to be set */
837 buf_set_u32(str9xpec_info->options, 63, 1, 1);
839 /* set option byte address */
840 str9xpec_set_address(bank, 0x50);
842 /* execute ISC_PROGRAM command */
843 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
845 field.num_bits = 64;
846 field.out_value = str9xpec_info->options;
847 field.in_value = NULL;
849 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
851 /* small delay before polling */
852 jtag_add_sleep(50);
854 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
856 do {
857 field.num_bits = 8;
858 field.out_value = NULL;
859 field.in_value = &status;
861 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
862 jtag_execute_queue();
864 } while (!(status & ISC_STATUS_BUSY));
866 str9xpec_isc_disable(bank);
868 return status;
871 COMMAND_HANDLER(str9xpec_handle_flash_options_write_command)
873 uint8_t status;
875 if (CMD_ARGC < 1)
876 return ERROR_COMMAND_SYNTAX_ERROR;
878 struct flash_bank *bank;
879 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
880 if (ERROR_OK != retval)
881 return retval;
883 status = str9xpec_write_options(bank);
885 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
886 return ERROR_FLASH_OPERATION_FAILED;
888 command_print(CMD_CTX, "str9xpec write options complete.\n"
889 "INFO: a reset or power cycle is required "
890 "for the new settings to take effect.");
892 return ERROR_OK;
895 COMMAND_HANDLER(str9xpec_handle_flash_options_cmap_command)
897 struct str9xpec_flash_controller *str9xpec_info = NULL;
899 if (CMD_ARGC < 2)
900 return ERROR_COMMAND_SYNTAX_ERROR;
902 struct flash_bank *bank;
903 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
904 if (ERROR_OK != retval)
905 return retval;
907 str9xpec_info = bank->driver_priv;
909 if (strcmp(CMD_ARGV[1], "bank1") == 0)
910 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 1);
911 else
912 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0);
914 return ERROR_OK;
917 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdthd_command)
919 struct str9xpec_flash_controller *str9xpec_info = NULL;
921 if (CMD_ARGC < 2)
922 return ERROR_COMMAND_SYNTAX_ERROR;
924 struct flash_bank *bank;
925 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
926 if (ERROR_OK != retval)
927 return retval;
929 str9xpec_info = bank->driver_priv;
931 if (strcmp(CMD_ARGV[1], "2.7v") == 0)
932 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 1);
933 else
934 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0);
936 return ERROR_OK;
939 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdsel_command)
941 struct str9xpec_flash_controller *str9xpec_info = NULL;
943 if (CMD_ARGC < 2)
944 return ERROR_COMMAND_SYNTAX_ERROR;
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 str9xpec_info = bank->driver_priv;
953 if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0)
954 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 1);
955 else
956 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0);
958 return ERROR_OK;
961 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdwarn_command)
963 struct str9xpec_flash_controller *str9xpec_info = NULL;
965 if (CMD_ARGC < 2)
966 return ERROR_COMMAND_SYNTAX_ERROR;
968 struct flash_bank *bank;
969 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
970 if (ERROR_OK != retval)
971 return retval;
973 str9xpec_info = bank->driver_priv;
975 if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0)
976 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 1);
977 else
978 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0);
980 return ERROR_OK;
983 COMMAND_HANDLER(str9xpec_handle_flash_lock_command)
985 uint8_t status;
987 if (CMD_ARGC < 1)
988 return ERROR_COMMAND_SYNTAX_ERROR;
990 struct flash_bank *bank;
991 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
992 if (ERROR_OK != retval)
993 return retval;
995 status = str9xpec_lock_device(bank);
997 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
998 return ERROR_FLASH_OPERATION_FAILED;
1000 return ERROR_OK;
1003 COMMAND_HANDLER(str9xpec_handle_flash_unlock_command)
1005 uint8_t status;
1007 if (CMD_ARGC < 1)
1008 return ERROR_COMMAND_SYNTAX_ERROR;
1010 struct flash_bank *bank;
1011 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1012 if (ERROR_OK != retval)
1013 return retval;
1015 status = str9xpec_unlock_device(bank);
1017 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1018 return ERROR_FLASH_OPERATION_FAILED;
1020 command_print(CMD_CTX, "str9xpec unlocked.\n"
1021 "INFO: a reset or power cycle is required "
1022 "for the new settings to take effect.");
1024 return ERROR_OK;
1027 COMMAND_HANDLER(str9xpec_handle_flash_enable_turbo_command)
1029 struct jtag_tap *tap0;
1030 struct jtag_tap *tap1;
1031 struct jtag_tap *tap2;
1032 struct str9xpec_flash_controller *str9xpec_info = NULL;
1034 if (CMD_ARGC < 1)
1035 return ERROR_COMMAND_SYNTAX_ERROR;
1037 struct flash_bank *bank;
1038 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1039 if (ERROR_OK != retval)
1040 return retval;
1042 str9xpec_info = bank->driver_priv;
1044 /* remove arm core from chain - enter turbo mode */
1045 tap0 = str9xpec_info->tap;
1046 if (tap0 == NULL) {
1047 /* things are *WRONG* */
1048 command_print(CMD_CTX, "**STR9FLASH** (tap0) invalid chain?");
1049 return ERROR_FAIL;
1051 tap1 = tap0->next_tap;
1052 if (tap1 == NULL) {
1053 /* things are *WRONG* */
1054 command_print(CMD_CTX, "**STR9FLASH** (tap1) invalid chain?");
1055 return ERROR_FAIL;
1057 tap2 = tap1->next_tap;
1058 if (tap2 == NULL) {
1059 /* things are *WRONG* */
1060 command_print(CMD_CTX, "**STR9FLASH** (tap2) invalid chain?");
1061 return ERROR_FAIL;
1064 /* enable turbo mode - TURBO-PROG-ENABLE */
1065 str9xpec_set_instr(tap2, 0xD, TAP_IDLE);
1066 retval = jtag_execute_queue();
1067 if (retval != ERROR_OK)
1068 return retval;
1070 /* modify scan chain - str9 core has been removed */
1071 tap1->enabled = 0;
1073 return ERROR_OK;
1076 COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command)
1078 struct jtag_tap *tap;
1079 struct str9xpec_flash_controller *str9xpec_info = NULL;
1081 if (CMD_ARGC < 1)
1082 return ERROR_COMMAND_SYNTAX_ERROR;
1084 struct flash_bank *bank;
1085 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1086 if (ERROR_OK != retval)
1087 return retval;
1089 str9xpec_info = bank->driver_priv;
1090 tap = str9xpec_info->tap;
1092 if (tap == NULL)
1093 return ERROR_FAIL;
1095 /* exit turbo mode via RESET */
1096 str9xpec_set_instr(tap, ISC_NOOP, TAP_IDLE);
1097 jtag_add_tlr();
1098 jtag_execute_queue();
1100 /* restore previous scan chain */
1101 if (tap->next_tap)
1102 tap->next_tap->enabled = 1;
1104 return ERROR_OK;
1107 static const struct command_registration str9xpec_config_command_handlers[] = {
1109 .name = "enable_turbo",
1110 .usage = "<bank>",
1111 .handler = str9xpec_handle_flash_enable_turbo_command,
1112 .mode = COMMAND_EXEC,
1113 .help = "enable str9xpec turbo mode",
1116 .name = "disable_turbo",
1117 .usage = "<bank>",
1118 .handler = str9xpec_handle_flash_disable_turbo_command,
1119 .mode = COMMAND_EXEC,
1120 .help = "disable str9xpec turbo mode",
1123 .name = "options_cmap",
1124 .usage = "<bank> <bank0 | bank1>",
1125 .handler = str9xpec_handle_flash_options_cmap_command,
1126 .mode = COMMAND_EXEC,
1127 .help = "configure str9xpec boot sector",
1130 .name = "options_lvdthd",
1131 .usage = "<bank> <2.4v | 2.7v>",
1132 .handler = str9xpec_handle_flash_options_lvdthd_command,
1133 .mode = COMMAND_EXEC,
1134 .help = "configure str9xpec lvd threshold",
1137 .name = "options_lvdsel",
1138 .usage = "<bank> <vdd | vdd_vddq>",
1139 .handler = str9xpec_handle_flash_options_lvdsel_command,
1140 .mode = COMMAND_EXEC,
1141 .help = "configure str9xpec lvd selection",
1144 .name = "options_lvdwarn",
1145 .usage = "<bank> <vdd | vdd_vddq>",
1146 .handler = str9xpec_handle_flash_options_lvdwarn_command,
1147 .mode = COMMAND_EXEC,
1148 .help = "configure str9xpec lvd warning",
1151 .name = "options_read",
1152 .usage = "<bank>",
1153 .handler = str9xpec_handle_flash_options_read_command,
1154 .mode = COMMAND_EXEC,
1155 .help = "read str9xpec options",
1158 .name = "options_write",
1159 .usage = "<bank>",
1160 .handler = str9xpec_handle_flash_options_write_command,
1161 .mode = COMMAND_EXEC,
1162 .help = "write str9xpec options",
1165 .name = "lock",
1166 .usage = "<bank>",
1167 .handler = str9xpec_handle_flash_lock_command,
1168 .mode = COMMAND_EXEC,
1169 .help = "lock str9xpec device",
1172 .name = "unlock",
1173 .usage = "<bank>",
1174 .handler = str9xpec_handle_flash_unlock_command,
1175 .mode = COMMAND_EXEC,
1176 .help = "unlock str9xpec device",
1179 .name = "part_id",
1180 .handler = str9xpec_handle_part_id_command,
1181 .mode = COMMAND_EXEC,
1182 .help = "print part id of str9xpec flash bank <num>",
1184 COMMAND_REGISTRATION_DONE
1187 static const struct command_registration str9xpec_command_handlers[] = {
1189 .name = "str9xpec",
1190 .mode = COMMAND_ANY,
1191 .help = "str9xpec flash command group",
1192 .usage = "",
1193 .chain = str9xpec_config_command_handlers,
1195 COMMAND_REGISTRATION_DONE
1198 struct flash_driver str9xpec_flash = {
1199 .name = "str9xpec",
1200 .commands = str9xpec_command_handlers,
1201 .flash_bank_command = str9xpec_flash_bank_command,
1202 .erase = str9xpec_erase,
1203 .protect = str9xpec_protect,
1204 .write = str9xpec_write,
1205 .read = default_flash_read,
1206 .probe = str9xpec_probe,
1207 .auto_probe = str9xpec_probe,
1208 .erase_check = str9xpec_erase_check,
1209 .protect_check = str9xpec_protect_check,