update files to correct FSF address
[openocd.git] / src / flash / nor / str9xpec.c
blobda6c83e28bef83b29e393071e1e9176f16101a85
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 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
22 ***************************************************************************/
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
28 #include "imp.h"
29 #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 {
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 {
72 struct jtag_tap *tap;
73 uint32_t *sector_bits;
74 int chain_pos;
75 int isc_enable;
76 uint8_t options[8];
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)
85 if (tap == NULL)
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);
93 field.out_value = t;
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);
99 free(t);
102 return ERROR_OK;
105 static uint8_t str9xpec_isc_status(struct jtag_tap *tap)
107 struct scan_field field;
108 uint8_t status;
110 if (str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE) != ERROR_OK)
111 return ISC_STATUS_ERROR;
113 field.num_bits = 8;
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");
126 return status;
129 static int str9xpec_isc_enable(struct flash_bank *bank)
131 uint8_t status;
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)
138 return ERROR_OK;
140 /* enter isc mode */
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");
152 return ERROR_OK;
155 static int str9xpec_isc_disable(struct flash_bank *bank)
157 uint8_t status;
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)
164 return ERROR_OK;
166 if (str9xpec_set_instr(tap, ISC_DISABLE, TAP_IDLE) != ERROR_OK)
167 return ERROR_TARGET_INVALID;
169 /* delay to handle aborts */
170 jtag_add_sleep(50);
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");
180 return ERROR_OK;
183 static int str9xpec_read_config(struct flash_bank *bank)
185 struct scan_field field;
186 uint8_t status;
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);
198 field.num_bits = 64;
199 field.out_value = NULL;
200 field.in_value = str9xpec_info->options;
202 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
203 jtag_execute_queue();
205 status = str9xpec_isc_status(tap);
207 return status;
210 static int str9xpec_build_block_list(struct flash_bank *bank)
212 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
214 int i;
215 int num_sectors;
216 int b0_sectors = 0, b1_sectors = 0;
217 uint32_t offset = 0;
218 int b1_size = 0x2000;
220 switch (bank->size) {
221 case (256 * 1024):
222 b0_sectors = 4;
223 break;
224 case (512 * 1024):
225 b0_sectors = 8;
226 break;
227 case (1024 * 1024):
228 b0_sectors = 16;
229 break;
230 case (2048 * 1024):
231 b0_sectors = 32;
232 break;
233 case (128 * 1024):
234 b1_size = 0x4000;
235 b1_sectors = 8;
236 break;
237 case (32 * 1024):
238 b1_sectors = 4;
239 break;
240 default:
241 LOG_ERROR("BUG: unknown bank->size encountered");
242 exit(-1);
245 num_sectors = b0_sectors + b1_sectors;
247 bank->num_sectors = num_sectors;
248 bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);
249 str9xpec_info->sector_bits = malloc(sizeof(uint32_t) * num_sectors);
251 num_sectors = 0;
253 for (i = 0; i < b0_sectors; i++) {
254 bank->sectors[num_sectors].offset = offset;
255 bank->sectors[num_sectors].size = 0x10000;
256 offset += bank->sectors[i].size;
257 bank->sectors[num_sectors].is_erased = -1;
258 bank->sectors[num_sectors].is_protected = 1;
259 str9xpec_info->sector_bits[num_sectors++] = i;
262 for (i = 0; i < b1_sectors; i++) {
263 bank->sectors[num_sectors].offset = offset;
264 bank->sectors[num_sectors].size = b1_size;
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 + 32;
271 return ERROR_OK;
274 /* flash bank str9x <base> <size> 0 0 <target#>
276 FLASH_BANK_COMMAND_HANDLER(str9xpec_flash_bank_command)
278 struct str9xpec_flash_controller *str9xpec_info;
279 struct arm *arm = NULL;
280 struct arm7_9_common *arm7_9 = NULL;
281 struct arm_jtag *jtag_info = NULL;
283 if (CMD_ARGC < 6)
284 return ERROR_COMMAND_SYNTAX_ERROR;
286 str9xpec_info = malloc(sizeof(struct str9xpec_flash_controller));
287 bank->driver_priv = str9xpec_info;
289 /* REVISIT verify that the jtag position of flash controller is
290 * right after *THIS* core, which must be a STR9xx core ...
292 arm = bank->target->arch_info;
293 arm7_9 = arm->arch_info;
294 jtag_info = &arm7_9->jtag_info;
296 /* The core is the next tap after the flash controller in the chain */
297 str9xpec_info->tap = jtag_tap_by_position(jtag_info->tap->abs_chain_position - 1);
298 str9xpec_info->isc_enable = 0;
300 str9xpec_build_block_list(bank);
302 /* clear option byte register */
303 buf_set_u32(str9xpec_info->options, 0, 64, 0);
305 return ERROR_OK;
308 static int str9xpec_blank_check(struct flash_bank *bank, int first, int last)
310 struct scan_field field;
311 uint8_t status;
312 struct jtag_tap *tap;
313 int i;
314 uint8_t *buffer = NULL;
316 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
318 tap = str9xpec_info->tap;
320 if (!str9xpec_info->isc_enable)
321 str9xpec_isc_enable(bank);
323 if (!str9xpec_info->isc_enable)
324 return ERROR_FLASH_OPERATION_FAILED;
326 buffer = calloc(DIV_ROUND_UP(64, 8), 1);
328 LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first, last);
330 for (i = first; i <= last; i++)
331 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
333 /* execute ISC_BLANK_CHECK command */
334 str9xpec_set_instr(tap, ISC_BLANK_CHECK, TAP_IRPAUSE);
336 field.num_bits = 64;
337 field.out_value = buffer;
338 field.in_value = NULL;
340 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
341 jtag_add_sleep(40000);
343 /* read blank check result */
344 field.num_bits = 64;
345 field.out_value = NULL;
346 field.in_value = buffer;
348 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
349 jtag_execute_queue();
351 status = str9xpec_isc_status(tap);
353 for (i = first; i <= last; i++) {
354 if (buf_get_u32(buffer, str9xpec_info->sector_bits[i], 1))
355 bank->sectors[i].is_erased = 0;
356 else
357 bank->sectors[i].is_erased = 1;
360 free(buffer);
362 str9xpec_isc_disable(bank);
364 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
365 return ERROR_FLASH_OPERATION_FAILED;
366 return ERROR_OK;
369 static int str9xpec_protect_check(struct flash_bank *bank)
371 uint8_t status;
372 int i;
374 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
376 status = str9xpec_read_config(bank);
378 for (i = 0; i < bank->num_sectors; i++) {
379 if (buf_get_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1))
380 bank->sectors[i].is_protected = 1;
381 else
382 bank->sectors[i].is_protected = 0;
385 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
386 return ERROR_FLASH_OPERATION_FAILED;
387 return ERROR_OK;
390 static int str9xpec_erase_area(struct flash_bank *bank, int first, int last)
392 struct scan_field field;
393 uint8_t status;
394 struct jtag_tap *tap;
395 int i;
396 uint8_t *buffer = NULL;
398 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
400 tap = str9xpec_info->tap;
402 if (!str9xpec_info->isc_enable)
403 str9xpec_isc_enable(bank);
405 if (!str9xpec_info->isc_enable)
406 return ISC_STATUS_ERROR;
408 buffer = calloc(DIV_ROUND_UP(64, 8), 1);
410 LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first, last);
412 /* last bank: 0xFF signals a full erase (unlock complete device) */
413 /* last bank: 0xFE signals a option byte erase */
414 if (last == 0xFF) {
415 for (i = 0; i < 64; i++)
416 buf_set_u32(buffer, i, 1, 1);
417 } else if (last == 0xFE)
418 buf_set_u32(buffer, 49, 1, 1);
419 else {
420 for (i = first; i <= last; i++)
421 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
424 LOG_DEBUG("ISC_ERASE");
426 /* execute ISC_ERASE command */
427 str9xpec_set_instr(tap, ISC_ERASE, TAP_IRPAUSE);
429 field.num_bits = 64;
430 field.out_value = buffer;
431 field.in_value = NULL;
433 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
434 jtag_execute_queue();
436 jtag_add_sleep(10);
438 /* wait for erase completion */
439 while (!((status = str9xpec_isc_status(tap)) & ISC_STATUS_BUSY))
440 alive_sleep(1);
442 free(buffer);
444 str9xpec_isc_disable(bank);
446 return status;
449 static int str9xpec_erase(struct flash_bank *bank, int first, int last)
451 int status;
453 status = str9xpec_erase_area(bank, first, last);
455 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
456 return ERROR_FLASH_OPERATION_FAILED;
458 return ERROR_OK;
461 static int str9xpec_lock_device(struct flash_bank *bank)
463 struct scan_field field;
464 uint8_t status;
465 struct jtag_tap *tap;
466 struct str9xpec_flash_controller *str9xpec_info = NULL;
468 str9xpec_info = bank->driver_priv;
469 tap = str9xpec_info->tap;
471 if (!str9xpec_info->isc_enable)
472 str9xpec_isc_enable(bank);
474 if (!str9xpec_info->isc_enable)
475 return ISC_STATUS_ERROR;
477 /* set security address */
478 str9xpec_set_address(bank, 0x80);
480 /* execute ISC_PROGRAM command */
481 str9xpec_set_instr(tap, ISC_PROGRAM_SECURITY, TAP_IDLE);
483 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
485 do {
486 field.num_bits = 8;
487 field.out_value = NULL;
488 field.in_value = &status;
490 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
491 jtag_execute_queue();
493 } while (!(status & ISC_STATUS_BUSY));
495 str9xpec_isc_disable(bank);
497 return status;
500 static int str9xpec_unlock_device(struct flash_bank *bank)
502 uint8_t status;
504 status = str9xpec_erase_area(bank, 0, 255);
506 return status;
509 static int str9xpec_protect(struct flash_bank *bank, int set, int first, int last)
511 uint8_t status;
512 int i;
514 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
516 status = str9xpec_read_config(bank);
518 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
519 return ERROR_FLASH_OPERATION_FAILED;
521 LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first, last);
523 /* last bank: 0xFF signals a full device protect */
524 if (last == 0xFF) {
525 if (set)
526 status = str9xpec_lock_device(bank);
527 else {
528 /* perform full erase to unlock device */
529 status = str9xpec_unlock_device(bank);
531 } else {
532 for (i = first; i <= last; i++) {
533 if (set)
534 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 1);
535 else
536 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 0);
539 status = str9xpec_write_options(bank);
542 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
543 return ERROR_FLASH_OPERATION_FAILED;
545 return ERROR_OK;
548 static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector)
550 struct jtag_tap *tap;
551 struct scan_field field;
552 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
554 tap = str9xpec_info->tap;
556 /* set flash controller address */
557 str9xpec_set_instr(tap, ISC_ADDRESS_SHIFT, TAP_IRPAUSE);
559 field.num_bits = 8;
560 field.out_value = &sector;
561 field.in_value = NULL;
563 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
565 return ERROR_OK;
568 static int str9xpec_write(struct flash_bank *bank, uint8_t *buffer,
569 uint32_t offset, uint32_t count)
571 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
572 uint32_t dwords_remaining = (count / 8);
573 uint32_t bytes_remaining = (count & 0x00000007);
574 uint32_t bytes_written = 0;
575 uint8_t status;
576 uint32_t check_address = offset;
577 struct jtag_tap *tap;
578 struct scan_field field;
579 uint8_t *scanbuf;
580 int i;
581 int first_sector = 0;
582 int last_sector = 0;
584 tap = str9xpec_info->tap;
586 if (!str9xpec_info->isc_enable)
587 str9xpec_isc_enable(bank);
589 if (!str9xpec_info->isc_enable)
590 return ERROR_FLASH_OPERATION_FAILED;
592 if (offset & 0x7) {
593 LOG_WARNING("offset 0x%" PRIx32 " breaks required 8-byte alignment", offset);
594 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
597 for (i = 0; i < bank->num_sectors; i++) {
598 uint32_t sec_start = bank->sectors[i].offset;
599 uint32_t sec_end = sec_start + bank->sectors[i].size;
601 /* check if destination falls within the current sector */
602 if ((check_address >= sec_start) && (check_address < sec_end)) {
603 /* check if destination ends in the current sector */
604 if (offset + count < sec_end)
605 check_address = offset + count;
606 else
607 check_address = sec_end;
610 if ((offset >= sec_start) && (offset < sec_end))
611 first_sector = i;
613 if ((offset + count >= sec_start) && (offset + count < sec_end))
614 last_sector = i;
617 if (check_address != offset + count)
618 return ERROR_FLASH_DST_OUT_OF_BANK;
620 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
622 scanbuf = calloc(DIV_ROUND_UP(64, 8), 1);
624 LOG_DEBUG("ISC_PROGRAM");
626 for (i = first_sector; i <= last_sector; i++) {
627 str9xpec_set_address(bank, str9xpec_info->sector_bits[i]);
629 dwords_remaining = dwords_remaining < (bank->sectors[i].size/8)
630 ? dwords_remaining : (bank->sectors[i].size/8);
632 while (dwords_remaining > 0) {
633 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
635 field.num_bits = 64;
636 field.out_value = (buffer + bytes_written);
637 field.in_value = NULL;
639 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
641 /* small delay before polling */
642 jtag_add_sleep(50);
644 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
646 do {
647 field.num_bits = 8;
648 field.out_value = NULL;
649 field.in_value = scanbuf;
651 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
652 jtag_execute_queue();
654 status = buf_get_u32(scanbuf, 0, 8);
656 } while (!(status & ISC_STATUS_BUSY));
658 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
659 return ERROR_FLASH_OPERATION_FAILED;
661 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
662 return ERROR_FLASH_OPERATION_FAILED; */
664 dwords_remaining--;
665 bytes_written += 8;
669 if (bytes_remaining) {
670 uint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
672 /* copy the last remaining bytes into the write buffer */
673 memcpy(last_dword, buffer+bytes_written, bytes_remaining);
675 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
677 field.num_bits = 64;
678 field.out_value = last_dword;
679 field.in_value = NULL;
681 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
683 /* small delay before polling */
684 jtag_add_sleep(50);
686 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
688 do {
689 field.num_bits = 8;
690 field.out_value = NULL;
691 field.in_value = scanbuf;
693 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
694 jtag_execute_queue();
696 status = buf_get_u32(scanbuf, 0, 8);
698 } while (!(status & ISC_STATUS_BUSY));
700 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
701 return ERROR_FLASH_OPERATION_FAILED;
703 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
704 return ERROR_FLASH_OPERATION_FAILED; */
707 free(scanbuf);
709 str9xpec_isc_disable(bank);
711 return ERROR_OK;
714 static int str9xpec_probe(struct flash_bank *bank)
716 return ERROR_OK;
719 COMMAND_HANDLER(str9xpec_handle_part_id_command)
721 struct scan_field field;
722 uint8_t *buffer = NULL;
723 struct jtag_tap *tap;
724 uint32_t idcode;
725 struct str9xpec_flash_controller *str9xpec_info = NULL;
727 if (CMD_ARGC < 1)
728 return ERROR_COMMAND_SYNTAX_ERROR;
730 struct flash_bank *bank;
731 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
732 if (ERROR_OK != retval)
733 return retval;
735 str9xpec_info = bank->driver_priv;
736 tap = str9xpec_info->tap;
738 buffer = calloc(DIV_ROUND_UP(32, 8), 1);
740 str9xpec_set_instr(tap, ISC_IDCODE, TAP_IRPAUSE);
742 field.num_bits = 32;
743 field.out_value = NULL;
744 field.in_value = buffer;
746 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
747 jtag_execute_queue();
749 idcode = buf_get_u32(buffer, 0, 32);
751 command_print(CMD_CTX, "str9xpec part id: 0x%8.8" PRIx32 "", idcode);
753 free(buffer);
755 return ERROR_OK;
758 static int str9xpec_erase_check(struct flash_bank *bank)
760 return str9xpec_blank_check(bank, 0, bank->num_sectors - 1);
763 static int get_str9xpec_info(struct flash_bank *bank, char *buf, int buf_size)
765 snprintf(buf, buf_size, "str9xpec flash driver info");
766 return ERROR_OK;
769 COMMAND_HANDLER(str9xpec_handle_flash_options_read_command)
771 uint8_t status;
772 struct str9xpec_flash_controller *str9xpec_info = NULL;
774 if (CMD_ARGC < 1)
775 return ERROR_COMMAND_SYNTAX_ERROR;
777 struct flash_bank *bank;
778 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
779 if (ERROR_OK != retval)
780 return retval;
782 str9xpec_info = bank->driver_priv;
784 status = str9xpec_read_config(bank);
786 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
787 return ERROR_FLASH_OPERATION_FAILED;
789 /* boot bank */
790 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1))
791 command_print(CMD_CTX, "CS Map: bank1");
792 else
793 command_print(CMD_CTX, "CS Map: bank0");
795 /* OTP lock */
796 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1))
797 command_print(CMD_CTX, "OTP Lock: OTP Locked");
798 else
799 command_print(CMD_CTX, "OTP Lock: OTP Unlocked");
801 /* LVD Threshold */
802 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1))
803 command_print(CMD_CTX, "LVD Threshold: 2.7v");
804 else
805 command_print(CMD_CTX, "LVD Threshold: 2.4v");
807 /* LVD reset warning */
808 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1))
809 command_print(CMD_CTX, "LVD Reset Warning: VDD or VDDQ Inputs");
810 else
811 command_print(CMD_CTX, "LVD Reset Warning: VDD Input Only");
813 /* LVD reset select */
814 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1))
815 command_print(CMD_CTX, "LVD Reset Selection: VDD or VDDQ Inputs");
816 else
817 command_print(CMD_CTX, "LVD Reset Selection: VDD Input Only");
819 return ERROR_OK;
822 static int str9xpec_write_options(struct flash_bank *bank)
824 struct scan_field field;
825 uint8_t status;
826 struct jtag_tap *tap;
827 struct str9xpec_flash_controller *str9xpec_info = NULL;
829 str9xpec_info = bank->driver_priv;
830 tap = str9xpec_info->tap;
832 /* erase config options first */
833 status = str9xpec_erase_area(bank, 0xFE, 0xFE);
835 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
836 return status;
838 if (!str9xpec_info->isc_enable)
839 str9xpec_isc_enable(bank);
841 if (!str9xpec_info->isc_enable)
842 return ISC_STATUS_ERROR;
844 /* according to data 64th bit has to be set */
845 buf_set_u32(str9xpec_info->options, 63, 1, 1);
847 /* set option byte address */
848 str9xpec_set_address(bank, 0x50);
850 /* execute ISC_PROGRAM command */
851 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
853 field.num_bits = 64;
854 field.out_value = str9xpec_info->options;
855 field.in_value = NULL;
857 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
859 /* small delay before polling */
860 jtag_add_sleep(50);
862 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
864 do {
865 field.num_bits = 8;
866 field.out_value = NULL;
867 field.in_value = &status;
869 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
870 jtag_execute_queue();
872 } while (!(status & ISC_STATUS_BUSY));
874 str9xpec_isc_disable(bank);
876 return status;
879 COMMAND_HANDLER(str9xpec_handle_flash_options_write_command)
881 uint8_t status;
883 if (CMD_ARGC < 1)
884 return ERROR_COMMAND_SYNTAX_ERROR;
886 struct flash_bank *bank;
887 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
888 if (ERROR_OK != retval)
889 return retval;
891 status = str9xpec_write_options(bank);
893 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
894 return ERROR_FLASH_OPERATION_FAILED;
896 command_print(CMD_CTX, "str9xpec write options complete.\n"
897 "INFO: a reset or power cycle is required "
898 "for the new settings to take effect.");
900 return ERROR_OK;
903 COMMAND_HANDLER(str9xpec_handle_flash_options_cmap_command)
905 struct str9xpec_flash_controller *str9xpec_info = NULL;
907 if (CMD_ARGC < 2)
908 return ERROR_COMMAND_SYNTAX_ERROR;
910 struct flash_bank *bank;
911 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
912 if (ERROR_OK != retval)
913 return retval;
915 str9xpec_info = bank->driver_priv;
917 if (strcmp(CMD_ARGV[1], "bank1") == 0)
918 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 1);
919 else
920 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0);
922 return ERROR_OK;
925 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdthd_command)
927 struct str9xpec_flash_controller *str9xpec_info = NULL;
929 if (CMD_ARGC < 2)
930 return ERROR_COMMAND_SYNTAX_ERROR;
932 struct flash_bank *bank;
933 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
934 if (ERROR_OK != retval)
935 return retval;
937 str9xpec_info = bank->driver_priv;
939 if (strcmp(CMD_ARGV[1], "2.7v") == 0)
940 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 1);
941 else
942 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0);
944 return ERROR_OK;
947 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdsel_command)
949 struct str9xpec_flash_controller *str9xpec_info = NULL;
951 if (CMD_ARGC < 2)
952 return ERROR_COMMAND_SYNTAX_ERROR;
954 struct flash_bank *bank;
955 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
956 if (ERROR_OK != retval)
957 return retval;
959 str9xpec_info = bank->driver_priv;
961 if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0)
962 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 1);
963 else
964 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0);
966 return ERROR_OK;
969 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdwarn_command)
971 struct str9xpec_flash_controller *str9xpec_info = NULL;
973 if (CMD_ARGC < 2)
974 return ERROR_COMMAND_SYNTAX_ERROR;
976 struct flash_bank *bank;
977 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
978 if (ERROR_OK != retval)
979 return retval;
981 str9xpec_info = bank->driver_priv;
983 if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0)
984 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 1);
985 else
986 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0);
988 return ERROR_OK;
991 COMMAND_HANDLER(str9xpec_handle_flash_lock_command)
993 uint8_t status;
995 if (CMD_ARGC < 1)
996 return ERROR_COMMAND_SYNTAX_ERROR;
998 struct flash_bank *bank;
999 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1000 if (ERROR_OK != retval)
1001 return retval;
1003 status = str9xpec_lock_device(bank);
1005 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1006 return ERROR_FLASH_OPERATION_FAILED;
1008 return ERROR_OK;
1011 COMMAND_HANDLER(str9xpec_handle_flash_unlock_command)
1013 uint8_t status;
1015 if (CMD_ARGC < 1)
1016 return ERROR_COMMAND_SYNTAX_ERROR;
1018 struct flash_bank *bank;
1019 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1020 if (ERROR_OK != retval)
1021 return retval;
1023 status = str9xpec_unlock_device(bank);
1025 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1026 return ERROR_FLASH_OPERATION_FAILED;
1028 command_print(CMD_CTX, "str9xpec unlocked.\n"
1029 "INFO: a reset or power cycle is required "
1030 "for the new settings to take effect.");
1032 return ERROR_OK;
1035 COMMAND_HANDLER(str9xpec_handle_flash_enable_turbo_command)
1037 struct jtag_tap *tap0;
1038 struct jtag_tap *tap1;
1039 struct jtag_tap *tap2;
1040 struct str9xpec_flash_controller *str9xpec_info = NULL;
1042 if (CMD_ARGC < 1)
1043 return ERROR_COMMAND_SYNTAX_ERROR;
1045 struct flash_bank *bank;
1046 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1047 if (ERROR_OK != retval)
1048 return retval;
1050 str9xpec_info = bank->driver_priv;
1052 /* remove arm core from chain - enter turbo mode */
1053 tap0 = str9xpec_info->tap;
1054 if (tap0 == NULL) {
1055 /* things are *WRONG* */
1056 command_print(CMD_CTX, "**STR9FLASH** (tap0) invalid chain?");
1057 return ERROR_FAIL;
1059 tap1 = tap0->next_tap;
1060 if (tap1 == NULL) {
1061 /* things are *WRONG* */
1062 command_print(CMD_CTX, "**STR9FLASH** (tap1) invalid chain?");
1063 return ERROR_FAIL;
1065 tap2 = tap1->next_tap;
1066 if (tap2 == NULL) {
1067 /* things are *WRONG* */
1068 command_print(CMD_CTX, "**STR9FLASH** (tap2) invalid chain?");
1069 return ERROR_FAIL;
1072 /* enable turbo mode - TURBO-PROG-ENABLE */
1073 str9xpec_set_instr(tap2, 0xD, TAP_IDLE);
1074 retval = jtag_execute_queue();
1075 if (retval != ERROR_OK)
1076 return retval;
1078 /* modify scan chain - str9 core has been removed */
1079 tap1->enabled = 0;
1081 return ERROR_OK;
1084 COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command)
1086 struct jtag_tap *tap;
1087 struct str9xpec_flash_controller *str9xpec_info = NULL;
1089 if (CMD_ARGC < 1)
1090 return ERROR_COMMAND_SYNTAX_ERROR;
1092 struct flash_bank *bank;
1093 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1094 if (ERROR_OK != retval)
1095 return retval;
1097 str9xpec_info = bank->driver_priv;
1098 tap = str9xpec_info->tap;
1100 if (tap == NULL)
1101 return ERROR_FAIL;
1103 /* exit turbo mode via RESET */
1104 str9xpec_set_instr(tap, ISC_NOOP, TAP_IDLE);
1105 jtag_add_tlr();
1106 jtag_execute_queue();
1108 /* restore previous scan chain */
1109 if (tap->next_tap)
1110 tap->next_tap->enabled = 1;
1112 return ERROR_OK;
1115 static const struct command_registration str9xpec_config_command_handlers[] = {
1117 .name = "enable_turbo",
1118 .usage = "<bank>",
1119 .handler = str9xpec_handle_flash_enable_turbo_command,
1120 .mode = COMMAND_EXEC,
1121 .help = "enable str9xpec turbo mode",
1124 .name = "disable_turbo",
1125 .usage = "<bank>",
1126 .handler = str9xpec_handle_flash_disable_turbo_command,
1127 .mode = COMMAND_EXEC,
1128 .help = "disable str9xpec turbo mode",
1131 .name = "options_cmap",
1132 .usage = "<bank> <bank0 | bank1>",
1133 .handler = str9xpec_handle_flash_options_cmap_command,
1134 .mode = COMMAND_EXEC,
1135 .help = "configure str9xpec boot sector",
1138 .name = "options_lvdthd",
1139 .usage = "<bank> <2.4v | 2.7v>",
1140 .handler = str9xpec_handle_flash_options_lvdthd_command,
1141 .mode = COMMAND_EXEC,
1142 .help = "configure str9xpec lvd threshold",
1145 .name = "options_lvdsel",
1146 .usage = "<bank> <vdd | vdd_vddq>",
1147 .handler = str9xpec_handle_flash_options_lvdsel_command,
1148 .mode = COMMAND_EXEC,
1149 .help = "configure str9xpec lvd selection",
1152 .name = "options_lvdwarn",
1153 .usage = "<bank> <vdd | vdd_vddq>",
1154 .handler = str9xpec_handle_flash_options_lvdwarn_command,
1155 .mode = COMMAND_EXEC,
1156 .help = "configure str9xpec lvd warning",
1159 .name = "options_read",
1160 .usage = "<bank>",
1161 .handler = str9xpec_handle_flash_options_read_command,
1162 .mode = COMMAND_EXEC,
1163 .help = "read str9xpec options",
1166 .name = "options_write",
1167 .usage = "<bank>",
1168 .handler = str9xpec_handle_flash_options_write_command,
1169 .mode = COMMAND_EXEC,
1170 .help = "write str9xpec options",
1173 .name = "lock",
1174 .usage = "<bank>",
1175 .handler = str9xpec_handle_flash_lock_command,
1176 .mode = COMMAND_EXEC,
1177 .help = "lock str9xpec device",
1180 .name = "unlock",
1181 .usage = "<bank>",
1182 .handler = str9xpec_handle_flash_unlock_command,
1183 .mode = COMMAND_EXEC,
1184 .help = "unlock str9xpec device",
1187 .name = "part_id",
1188 .handler = str9xpec_handle_part_id_command,
1189 .mode = COMMAND_EXEC,
1190 .help = "print part id of str9xpec flash bank <num>",
1192 COMMAND_REGISTRATION_DONE
1195 static const struct command_registration str9xpec_command_handlers[] = {
1197 .name = "str9xpec",
1198 .mode = COMMAND_ANY,
1199 .help = "str9xpec flash command group",
1200 .usage = "",
1201 .chain = str9xpec_config_command_handlers,
1203 COMMAND_REGISTRATION_DONE
1206 struct flash_driver str9xpec_flash = {
1207 .name = "str9xpec",
1208 .commands = str9xpec_command_handlers,
1209 .flash_bank_command = str9xpec_flash_bank_command,
1210 .erase = str9xpec_erase,
1211 .protect = str9xpec_protect,
1212 .write = str9xpec_write,
1213 .read = default_flash_read,
1214 .probe = str9xpec_probe,
1215 .auto_probe = str9xpec_probe,
1216 .erase_check = str9xpec_erase_check,
1217 .protect_check = str9xpec_protect_check,
1218 .info = get_str9xpec_info,