1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
24 #include "replacements.h"
31 #include "arm7_9_common.h"
33 #include "binarybuffer.h"
40 str9xpec_mem_layout_t mem_layout_str9pec[] = {
41 {0x00000000, 0x10000, 0},
42 {0x00010000, 0x10000, 1},
43 {0x00020000, 0x10000, 2},
44 {0x00030000, 0x10000, 3},
45 {0x00040000, 0x10000, 4},
46 {0x00050000, 0x10000, 5},
47 {0x00060000, 0x10000, 6},
48 {0x00070000, 0x10000, 7},
49 {0x00080000, 0x02000, 32},
50 {0x00082000, 0x02000, 33},
51 {0x00084000, 0x02000, 34},
52 {0x00086000, 0x02000, 35}
55 int str9xpec_register_commands(struct command_context_s *cmd_ctx);
56 int str9xpec_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
57 int str9xpec_erase(struct flash_bank_s *bank, int first, int last);
58 int str9xpec_protect(struct flash_bank_s *bank, int set, int first, int last);
59 int str9xpec_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
60 int str9xpec_probe(struct flash_bank_s *bank);
61 int str9xpec_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
62 int str9xpec_protect_check(struct flash_bank_s *bank);
63 int str9xpec_erase_check(struct flash_bank_s *bank);
64 int str9xpec_info(struct flash_bank_s *bank, char *buf, int buf_size);
66 int str9xpec_erase_area(struct flash_bank_s *bank, int first, int last);
67 int str9xpec_set_address(struct flash_bank_s *bank, u8 sector);
68 int str9xpec_write_options(struct flash_bank_s *bank);
70 int str9xpec_handle_flash_options_cmap_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
71 int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
72 int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
73 int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
74 int str9xpec_handle_flash_options_read_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
75 int str9xpec_handle_flash_options_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
76 int str9xpec_handle_flash_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
77 int str9xpec_handle_flash_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
78 int str9xpec_handle_flash_enable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
79 int str9xpec_handle_flash_disable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
81 flash_driver_t str9xpec_flash =
84 .register_commands = str9xpec_register_commands,
85 .flash_bank_command = str9xpec_flash_bank_command,
86 .erase = str9xpec_erase,
87 .protect = str9xpec_protect,
88 .write = str9xpec_write,
89 .probe = str9xpec_probe,
90 .auto_probe = str9xpec_probe,
91 .erase_check = str9xpec_erase_check,
92 .protect_check = str9xpec_protect_check,
96 int str9xpec_register_commands(struct command_context_s *cmd_ctx)
98 command_t *str9xpec_cmd = register_command(cmd_ctx, NULL, "str9xpec", NULL, COMMAND_ANY, "str9xpec flash specific commands");
100 register_command(cmd_ctx, str9xpec_cmd, "enable_turbo", str9xpec_handle_flash_enable_turbo_command, COMMAND_EXEC,
101 "enable str9xpec turbo mode");
102 register_command(cmd_ctx, str9xpec_cmd, "disable_turbo", str9xpec_handle_flash_disable_turbo_command, COMMAND_EXEC,
103 "disable str9xpec turbo mode");
104 register_command(cmd_ctx, str9xpec_cmd, "options_cmap", str9xpec_handle_flash_options_cmap_command, COMMAND_EXEC,
105 "configure str9xpec boot sector");
106 register_command(cmd_ctx, str9xpec_cmd, "options_lvdthd", str9xpec_handle_flash_options_lvdthd_command, COMMAND_EXEC,
107 "configure str9xpec lvd threshold");
108 register_command(cmd_ctx, str9xpec_cmd, "options_lvdsel", str9xpec_handle_flash_options_lvdsel_command, COMMAND_EXEC,
109 "configure str9xpec lvd selection");
110 register_command(cmd_ctx, str9xpec_cmd, "options_lvdwarn", str9xpec_handle_flash_options_lvdwarn_command, COMMAND_EXEC,
111 "configure str9xpec lvd warning");
112 register_command(cmd_ctx, str9xpec_cmd, "options_read", str9xpec_handle_flash_options_read_command, COMMAND_EXEC,
113 "read str9xpec options");
114 register_command(cmd_ctx, str9xpec_cmd, "options_write", str9xpec_handle_flash_options_write_command, COMMAND_EXEC,
115 "write str9xpec options");
116 register_command(cmd_ctx, str9xpec_cmd, "lock", str9xpec_handle_flash_lock_command, COMMAND_EXEC,
117 "lock str9xpec device");
118 register_command(cmd_ctx, str9xpec_cmd, "unlock", str9xpec_handle_flash_unlock_command, COMMAND_EXEC,
119 "unlock str9xpec device");
120 register_command(cmd_ctx, str9xpec_cmd, "part_id", str9xpec_handle_part_id_command, COMMAND_EXEC,
121 "print part id of str9xpec flash bank <num>");
126 int str9xpec_set_instr(int chain_pos, u32 new_instr, enum tap_state end_state)
128 jtag_device_t *device = jtag_get_device(chain_pos);
132 LOG_DEBUG("Invalid Target");
133 return ERROR_TARGET_INVALID;
136 if (buf_get_u32(device->cur_instr, 0, device->ir_length) != new_instr)
140 field.device = chain_pos;
141 field.num_bits = device->ir_length;
142 field.out_value = calloc(CEIL(field.num_bits, 8), 1);
143 buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
144 field.out_mask = NULL;
145 field.in_value = NULL;
146 field.in_check_value = NULL;
147 field.in_check_mask = NULL;
148 field.in_handler = NULL;
149 field.in_handler_priv = NULL;
151 jtag_add_ir_scan(1, &field, end_state);
153 free(field.out_value);
159 u8 str9xpec_isc_status(int chain_pos)
164 if (str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI) != ERROR_OK)
165 return ISC_STATUS_ERROR;
167 field.device = chain_pos;
169 field.out_value = NULL;
170 field.out_mask = NULL;
171 field.in_value = &status;
172 field.in_check_value = NULL;
173 field.in_check_mask = NULL;
174 field.in_handler = NULL;
175 field.in_handler_priv = NULL;
177 jtag_add_dr_scan(1, &field, TAP_RTI);
178 jtag_execute_queue();
180 LOG_DEBUG("status: 0x%2.2x", status);
182 if (status & ISC_STATUS_SECURITY)
183 LOG_INFO("Device Security Bit Set");
188 int str9xpec_isc_enable(struct flash_bank_s *bank)
192 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
194 chain_pos = str9xpec_info->chain_pos;
196 if (str9xpec_info->isc_enable)
200 if (str9xpec_set_instr(chain_pos, ISC_ENABLE, TAP_RTI) != ERROR_OK)
201 return ERROR_TARGET_INVALID;
203 /* check ISC status */
204 status = str9xpec_isc_status(chain_pos);
205 if (status & ISC_STATUS_MODE)
207 /* we have entered isc mode */
208 str9xpec_info->isc_enable = 1;
209 LOG_DEBUG("ISC_MODE Enabled");
215 int str9xpec_isc_disable(struct flash_bank_s *bank)
219 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
221 chain_pos = str9xpec_info->chain_pos;
223 if (!str9xpec_info->isc_enable)
226 if (str9xpec_set_instr(chain_pos, ISC_DISABLE, TAP_RTI) != ERROR_OK)
227 return ERROR_TARGET_INVALID;
229 /* delay to handle aborts */
232 /* check ISC status */
233 status = str9xpec_isc_status(chain_pos);
234 if (!(status & ISC_STATUS_MODE))
236 /* we have left isc mode */
237 str9xpec_info->isc_enable = 0;
238 LOG_DEBUG("ISC_MODE Disabled");
244 int str9xpec_read_config(struct flash_bank_s *bank)
250 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
252 chain_pos = str9xpec_info->chain_pos;
254 LOG_DEBUG("ISC_CONFIGURATION");
256 /* execute ISC_CONFIGURATION command */
257 str9xpec_set_instr(chain_pos, ISC_CONFIGURATION, TAP_PI);
259 field.device = chain_pos;
261 field.out_value = NULL;
262 field.out_mask = NULL;
263 field.in_value = str9xpec_info->options;
264 field.in_check_value = NULL;
265 field.in_check_mask = NULL;
266 field.in_handler = NULL;
267 field.in_handler_priv = NULL;
269 jtag_add_dr_scan(1, &field, TAP_RTI);
270 jtag_execute_queue();
272 status = str9xpec_isc_status(chain_pos);
277 int str9xpec_build_block_list(struct flash_bank_s *bank)
279 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
282 int num_sectors = 0, b0_sectors = 0;
293 LOG_ERROR("BUG: unknown bank->size encountered");
297 /* include bank 1 sectors */
298 num_sectors = b0_sectors + 4;
299 bank->size += (32 * 1024);
301 bank->num_sectors = num_sectors;
302 bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors);
303 str9xpec_info->sector_bits = malloc(sizeof(u32) * num_sectors);
307 for (i = 0; i < b0_sectors; i++)
309 bank->sectors[num_sectors].offset = mem_layout_str9pec[i].sector_start;
310 bank->sectors[num_sectors].size = mem_layout_str9pec[i].sector_size;
311 bank->sectors[num_sectors].is_erased = -1;
312 bank->sectors[num_sectors].is_protected = 1;
313 str9xpec_info->sector_bits[num_sectors++] = mem_layout_str9pec[i].sector_bit;
316 for (i = 8; i < 12; i++)
318 bank->sectors[num_sectors].offset = mem_layout_str9pec[i].sector_start;
319 bank->sectors[num_sectors].size = mem_layout_str9pec[i].sector_size;
320 bank->sectors[num_sectors].is_erased = -1;
321 bank->sectors[num_sectors].is_protected = 1;
322 str9xpec_info->sector_bits[num_sectors++] = mem_layout_str9pec[i].sector_bit;
328 /* flash bank str9x <base> <size> 0 0 <target#>
330 int str9xpec_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
332 str9xpec_flash_controller_t *str9xpec_info;
333 armv4_5_common_t *armv4_5 = NULL;
334 arm7_9_common_t *arm7_9 = NULL;
335 arm_jtag_t *jtag_info = NULL;
339 LOG_WARNING("incomplete flash_bank str9x configuration");
340 return ERROR_FLASH_BANK_INVALID;
343 str9xpec_info = malloc(sizeof(str9xpec_flash_controller_t));
344 bank->driver_priv = str9xpec_info;
346 if (bank->base != 0x00000000)
348 LOG_WARNING("overriding flash base address for STR91x device with 0x00000000");
349 bank->base = 0x00000000;
352 /* find out jtag position of flash controller
353 * it is always after the arm966 core */
355 armv4_5 = bank->target->arch_info;
356 arm7_9 = armv4_5->arch_info;
357 jtag_info = &arm7_9->jtag_info;
359 str9xpec_info->chain_pos = (jtag_info->chain_pos - 1);
360 str9xpec_info->isc_enable = 0;
361 str9xpec_info->devarm = NULL;
363 str9xpec_build_block_list(bank);
365 /* clear option byte register */
366 buf_set_u32(str9xpec_info->options, 0, 64, 0);
371 int str9xpec_blank_check(struct flash_bank_s *bank, int first, int last)
379 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
381 chain_pos = str9xpec_info->chain_pos;
383 if (!str9xpec_info->isc_enable) {
384 str9xpec_isc_enable( bank );
387 if (!str9xpec_info->isc_enable) {
388 return ERROR_FLASH_OPERATION_FAILED;
391 buffer = calloc(CEIL(64, 8), 1);
393 LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first, last);
395 for (i = first; i <= last; i++) {
396 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
399 /* execute ISC_BLANK_CHECK command */
400 str9xpec_set_instr(chain_pos, ISC_BLANK_CHECK, TAP_PI);
402 field.device = chain_pos;
404 field.out_value = buffer;
405 field.out_mask = NULL;
406 field.in_value = NULL;
407 field.in_check_value = NULL;
408 field.in_check_mask = NULL;
409 field.in_handler = NULL;
410 field.in_handler_priv = NULL;
412 jtag_add_dr_scan(1, &field, TAP_RTI);
413 jtag_add_sleep(40000);
415 /* read blank check result */
416 field.device = chain_pos;
418 field.out_value = NULL;
419 field.out_mask = NULL;
420 field.in_value = buffer;
421 field.in_check_value = NULL;
422 field.in_check_mask = NULL;
423 field.in_handler = NULL;
424 field.in_handler_priv = NULL;
426 jtag_add_dr_scan(1, &field, TAP_PI);
427 jtag_execute_queue();
429 status = str9xpec_isc_status(chain_pos);
431 for (i = first; i <= last; i++)
433 if (buf_get_u32(buffer, str9xpec_info->sector_bits[i], 1))
434 bank->sectors[i].is_erased = 0;
436 bank->sectors[i].is_erased = 1;
441 str9xpec_isc_disable(bank);
443 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
444 return ERROR_FLASH_OPERATION_FAILED;
448 int str9xpec_protect_check(struct flash_bank_s *bank)
453 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
455 status = str9xpec_read_config(bank);
457 for (i = 0; i < bank->num_sectors; i++)
459 if (buf_get_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1))
460 bank->sectors[i].is_protected = 1;
462 bank->sectors[i].is_protected = 0;
465 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
466 return ERROR_FLASH_OPERATION_FAILED;
470 int str9xpec_erase_area(struct flash_bank_s *bank, int first, int last)
478 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
480 chain_pos = str9xpec_info->chain_pos;
482 if (!str9xpec_info->isc_enable) {
483 str9xpec_isc_enable( bank );
486 if (!str9xpec_info->isc_enable) {
487 return ISC_STATUS_ERROR;
490 buffer = calloc(CEIL(64, 8), 1);
492 LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first, last);
494 /* last bank: 0xFF signals a full erase (unlock complete device) */
495 /* last bank: 0xFE signals a option byte erase */
498 for (i = 0; i < 64; i++) {
499 buf_set_u32(buffer, i, 1, 1);
502 else if (last == 0xFE)
504 buf_set_u32(buffer, 49, 1, 1);
508 for (i = first; i <= last; i++) {
509 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
513 LOG_DEBUG("ISC_ERASE");
515 /* execute ISC_ERASE command */
516 str9xpec_set_instr(chain_pos, ISC_ERASE, TAP_PI);
518 field.device = chain_pos;
520 field.out_value = buffer;
521 field.out_mask = NULL;
522 field.in_value = NULL;
523 field.in_check_value = NULL;
524 field.in_check_mask = NULL;
525 field.in_handler = NULL;
526 field.in_handler_priv = NULL;
528 jtag_add_dr_scan(1, &field, TAP_RTI);
529 jtag_execute_queue();
533 /* wait for erase completion */
534 while (!((status = str9xpec_isc_status(chain_pos)) & ISC_STATUS_BUSY)) {
540 str9xpec_isc_disable(bank);
545 int str9xpec_erase(struct flash_bank_s *bank, int first, int last)
549 status = str9xpec_erase_area(bank, first, last);
551 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
552 return ERROR_FLASH_OPERATION_FAILED;
557 int str9xpec_lock_device(struct flash_bank_s *bank)
562 str9xpec_flash_controller_t *str9xpec_info = NULL;
564 str9xpec_info = bank->driver_priv;
565 chain_pos = str9xpec_info->chain_pos;
567 if (!str9xpec_info->isc_enable) {
568 str9xpec_isc_enable( bank );
571 if (!str9xpec_info->isc_enable) {
572 return ISC_STATUS_ERROR;
575 /* set security address */
576 str9xpec_set_address(bank, 0x80);
578 /* execute ISC_PROGRAM command */
579 str9xpec_set_instr(chain_pos, ISC_PROGRAM_SECURITY, TAP_RTI);
581 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
584 field.device = chain_pos;
586 field.out_value = NULL;
587 field.out_mask = NULL;
588 field.in_value = &status;
589 field.in_check_value = NULL;
590 field.in_check_mask = NULL;
591 field.in_handler = NULL;
592 field.in_handler_priv = NULL;
594 jtag_add_dr_scan(1, &field, -1);
595 jtag_execute_queue();
597 } while(!(status & ISC_STATUS_BUSY));
599 str9xpec_isc_disable(bank);
604 int str9xpec_unlock_device(struct flash_bank_s *bank)
608 status = str9xpec_erase_area(bank, 0, 255);
613 int str9xpec_protect(struct flash_bank_s *bank, int set, int first, int last)
618 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
620 status = str9xpec_read_config(bank);
622 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
623 return ERROR_FLASH_OPERATION_FAILED;
625 LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first, last);
627 /* last bank: 0xFF signals a full device protect */
632 status = str9xpec_lock_device(bank);
636 /* perform full erase to unlock device */
637 status = str9xpec_unlock_device(bank);
642 for (i = first; i <= last; i++)
645 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 1);
647 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 0);
650 status = str9xpec_write_options(bank);
653 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
654 return ERROR_FLASH_OPERATION_FAILED;
659 int str9xpec_set_address(struct flash_bank_s *bank, u8 sector)
663 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
665 chain_pos = str9xpec_info->chain_pos;
667 /* set flash controller address */
668 str9xpec_set_instr(chain_pos, ISC_ADDRESS_SHIFT, TAP_PI);
670 field.device = chain_pos;
672 field.out_value = §or;
673 field.out_mask = NULL;
674 field.in_value = NULL;
675 field.in_check_value = NULL;
676 field.in_check_mask = NULL;
677 field.in_handler = NULL;
678 field.in_handler_priv = NULL;
680 jtag_add_dr_scan(1, &field, -1);
685 int str9xpec_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
687 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
688 u32 dwords_remaining = (count / 8);
689 u32 bytes_remaining = (count & 0x00000007);
690 u32 bytes_written = 0;
692 u32 check_address = offset;
697 u32 first_sector = 0;
700 chain_pos = str9xpec_info->chain_pos;
702 if (!str9xpec_info->isc_enable) {
703 str9xpec_isc_enable(bank);
706 if (!str9xpec_info->isc_enable) {
707 return ERROR_FLASH_OPERATION_FAILED;
712 LOG_WARNING("offset 0x%x breaks required 8-byte alignment", offset);
713 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
716 for (i = 0; i < bank->num_sectors; i++)
718 u32 sec_start = bank->sectors[i].offset;
719 u32 sec_end = sec_start + bank->sectors[i].size;
721 /* check if destination falls within the current sector */
722 if ((check_address >= sec_start) && (check_address < sec_end))
724 /* check if destination ends in the current sector */
725 if (offset + count < sec_end)
726 check_address = offset + count;
728 check_address = sec_end;
731 if ((offset >= sec_start) && (offset < sec_end)){
735 if ((offset + count >= sec_start) && (offset + count < sec_end)){
740 if (check_address != offset + count)
741 return ERROR_FLASH_DST_OUT_OF_BANK;
743 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
745 scanbuf = calloc(CEIL(64, 8), 1);
747 LOG_DEBUG("ISC_PROGRAM");
749 for (i = first_sector; i <= last_sector; i++)
751 str9xpec_set_address(bank, str9xpec_info->sector_bits[i]);
753 dwords_remaining = dwords_remaining < (bank->sectors[i].size/8) ? dwords_remaining : (bank->sectors[i].size/8);
755 while (dwords_remaining > 0)
757 str9xpec_set_instr(chain_pos, ISC_PROGRAM, TAP_PI);
759 field.device = chain_pos;
761 field.out_value = (buffer + bytes_written);
762 field.out_mask = NULL;
763 field.in_value = NULL;
764 field.in_check_value = NULL;
765 field.in_check_mask = NULL;
766 field.in_handler = NULL;
767 field.in_handler_priv = NULL;
769 jtag_add_dr_scan(1, &field, TAP_RTI);
771 /* small delay before polling */
774 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
777 field.device = chain_pos;
779 field.out_value = NULL;
780 field.out_mask = NULL;
781 field.in_value = scanbuf;
782 field.in_check_value = NULL;
783 field.in_check_mask = NULL;
784 field.in_handler = NULL;
785 field.in_handler_priv = NULL;
787 jtag_add_dr_scan(1, &field, -1);
788 jtag_execute_queue();
790 status = buf_get_u32(scanbuf, 0, 8);
792 } while(!(status & ISC_STATUS_BUSY));
794 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
795 return ERROR_FLASH_OPERATION_FAILED;
797 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
798 return ERROR_FLASH_OPERATION_FAILED; */
807 u8 last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
810 while(bytes_remaining > 0)
812 last_dword[i++] = *(buffer + bytes_written);
817 str9xpec_set_instr(chain_pos, ISC_PROGRAM, TAP_PI);
819 field.device = chain_pos;
821 field.out_value = last_dword;
822 field.out_mask = NULL;
823 field.in_value = NULL;
824 field.in_check_value = NULL;
825 field.in_check_mask = NULL;
826 field.in_handler = NULL;
827 field.in_handler_priv = NULL;
829 jtag_add_dr_scan(1, &field, TAP_RTI);
831 /* small delay before polling */
834 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
837 field.device = chain_pos;
839 field.out_value = NULL;
840 field.out_mask = NULL;
841 field.in_value = scanbuf;
842 field.in_check_value = NULL;
843 field.in_check_mask = NULL;
844 field.in_handler = NULL;
845 field.in_handler_priv = NULL;
847 jtag_add_dr_scan(1, &field, -1);
848 jtag_execute_queue();
850 status = buf_get_u32(scanbuf, 0, 8);
852 } while(!(status & ISC_STATUS_BUSY));
854 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
855 return ERROR_FLASH_OPERATION_FAILED;
857 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
858 return ERROR_FLASH_OPERATION_FAILED; */
863 str9xpec_isc_disable(bank);
868 int str9xpec_probe(struct flash_bank_s *bank)
873 int str9xpec_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
880 str9xpec_flash_controller_t *str9xpec_info = NULL;
884 return ERROR_COMMAND_SYNTAX_ERROR;
887 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
890 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
894 str9xpec_info = bank->driver_priv;
895 chain_pos = str9xpec_info->chain_pos;
897 buffer = calloc(CEIL(32, 8), 1);
899 str9xpec_set_instr(chain_pos, ISC_IDCODE, TAP_PI);
901 field.device = chain_pos;
903 field.out_value = NULL;
904 field.out_mask = NULL;
905 field.in_value = buffer;
906 field.in_check_value = NULL;
907 field.in_check_mask = NULL;
908 field.in_handler = NULL;
909 field.in_handler_priv = NULL;
911 jtag_add_dr_scan(1, &field, TAP_RTI);
912 jtag_execute_queue();
914 idcode = buf_get_u32(buffer, 0, 32);
916 command_print(cmd_ctx, "str9xpec part id: 0x%8.8x", idcode);
923 int str9xpec_erase_check(struct flash_bank_s *bank)
925 return str9xpec_blank_check(bank, 0, bank->num_sectors - 1);
928 int str9xpec_info(struct flash_bank_s *bank, char *buf, int buf_size)
930 snprintf(buf, buf_size, "str9xpec flash driver info" );
934 int str9xpec_handle_flash_options_read_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
938 str9xpec_flash_controller_t *str9xpec_info = NULL;
942 command_print(cmd_ctx, "str9xpec options_read <bank>");
946 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
949 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
953 str9xpec_info = bank->driver_priv;
955 status = str9xpec_read_config(bank);
957 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
958 return ERROR_FLASH_OPERATION_FAILED;
961 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1))
962 command_print(cmd_ctx, "CS Map: bank1");
964 command_print(cmd_ctx, "CS Map: bank0");
967 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1))
968 command_print(cmd_ctx, "OTP Lock: OTP Locked");
970 command_print(cmd_ctx, "OTP Lock: OTP Unlocked");
973 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1))
974 command_print(cmd_ctx, "LVD Threshold: 2.7v");
976 command_print(cmd_ctx, "LVD Threshold: 2.4v");
978 /* LVD reset warning */
979 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1))
980 command_print(cmd_ctx, "LVD Reset Warning: VDD or VDDQ Inputs");
982 command_print(cmd_ctx, "LVD Reset Warning: VDD Input Only");
984 /* LVD reset select */
985 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1))
986 command_print(cmd_ctx, "LVD Reset Selection: VDD or VDDQ Inputs");
988 command_print(cmd_ctx, "LVD Reset Selection: VDD Input Only");
993 int str9xpec_write_options(struct flash_bank_s *bank)
998 str9xpec_flash_controller_t *str9xpec_info = NULL;
1000 str9xpec_info = bank->driver_priv;
1001 chain_pos = str9xpec_info->chain_pos;
1003 /* erase config options first */
1004 status = str9xpec_erase_area( bank, 0xFE, 0xFE );
1006 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1009 if (!str9xpec_info->isc_enable) {
1010 str9xpec_isc_enable( bank );
1013 if (!str9xpec_info->isc_enable) {
1014 return ISC_STATUS_ERROR;
1017 /* according to data 64th bit has to be set */
1018 buf_set_u32(str9xpec_info->options, 63, 1, 1);
1020 /* set option byte address */
1021 str9xpec_set_address(bank, 0x50);
1023 /* execute ISC_PROGRAM command */
1024 str9xpec_set_instr(chain_pos, ISC_PROGRAM, TAP_PI);
1026 field.device = chain_pos;
1027 field.num_bits = 64;
1028 field.out_value = str9xpec_info->options;
1029 field.out_mask = NULL;
1030 field.in_value = NULL;
1031 field.in_check_value = NULL;
1032 field.in_check_mask = NULL;
1033 field.in_handler = NULL;
1034 field.in_handler_priv = NULL;
1036 jtag_add_dr_scan(1, &field, TAP_RTI);
1038 /* small delay before polling */
1041 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
1044 field.device = chain_pos;
1046 field.out_value = NULL;
1047 field.out_mask = NULL;
1048 field.in_value = &status;
1049 field.in_check_value = NULL;
1050 field.in_check_mask = NULL;
1051 field.in_handler = NULL;
1052 field.in_handler_priv = NULL;
1054 jtag_add_dr_scan(1, &field, -1);
1055 jtag_execute_queue();
1057 } while(!(status & ISC_STATUS_BUSY));
1059 str9xpec_isc_disable(bank);
1064 int str9xpec_handle_flash_options_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1071 command_print(cmd_ctx, "str9xpec options_write <bank>");
1075 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1078 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1082 status = str9xpec_write_options(bank);
1084 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1085 return ERROR_FLASH_OPERATION_FAILED;
1090 int str9xpec_handle_flash_options_cmap_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1093 str9xpec_flash_controller_t *str9xpec_info = NULL;
1097 command_print(cmd_ctx, "str9xpec options_cmap <bank> <bank0|bank1>");
1101 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1104 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1108 str9xpec_info = bank->driver_priv;
1110 if (strcmp(args[1], "bank1") == 0)
1112 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 1);
1116 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0);
1122 int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1125 str9xpec_flash_controller_t *str9xpec_info = NULL;
1129 command_print(cmd_ctx, "str9xpec options_lvdthd <bank> <2.4v|2.7v>");
1133 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1136 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1140 str9xpec_info = bank->driver_priv;
1142 if (strcmp(args[1], "2.7v") == 0)
1144 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 1);
1148 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0);
1154 int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1157 str9xpec_flash_controller_t *str9xpec_info = NULL;
1161 command_print(cmd_ctx, "str9xpec options_lvdsel <bank> <vdd|vdd_vddq>");
1165 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1168 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1172 str9xpec_info = bank->driver_priv;
1174 if (strcmp(args[1], "vdd_vddq") == 0)
1176 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 1);
1180 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0);
1186 int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1189 str9xpec_flash_controller_t *str9xpec_info = NULL;
1193 command_print(cmd_ctx, "str9xpec options_lvdwarn <bank> <vdd|vdd_vddq>");
1197 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1200 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1204 str9xpec_info = bank->driver_priv;
1206 if (strcmp(args[1], "vdd_vddq") == 0)
1208 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 1);
1212 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0);
1218 int str9xpec_handle_flash_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1225 command_print(cmd_ctx, "str9xpec lock <bank>");
1229 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1232 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1236 status = str9xpec_lock_device(bank);
1238 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1239 return ERROR_FLASH_OPERATION_FAILED;
1244 int str9xpec_handle_flash_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1251 command_print(cmd_ctx, "str9xpec unlock <bank>");
1255 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1258 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1262 status = str9xpec_unlock_device(bank);
1264 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1265 return ERROR_FLASH_OPERATION_FAILED;
1270 int str9xpec_handle_flash_enable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1274 jtag_device_t* dev0;
1275 jtag_device_t* dev2;
1276 str9xpec_flash_controller_t *str9xpec_info = NULL;
1280 command_print(cmd_ctx, "str9xpec enable_turbo <bank>");
1284 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1287 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1291 str9xpec_info = bank->driver_priv;
1293 chain_pos = str9xpec_info->chain_pos;
1295 /* remove arm core from chain - enter turbo mode */
1297 str9xpec_set_instr(chain_pos+2, 0xD, TAP_RTI);
1298 jtag_execute_queue();
1300 /* modify scan chain - str9 core has been removed */
1301 dev0 = jtag_get_device(chain_pos);
1302 str9xpec_info->devarm = jtag_get_device(chain_pos+1);
1303 dev2 = jtag_get_device(chain_pos+2);
1310 int str9xpec_handle_flash_disable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1314 jtag_device_t* dev0;
1315 str9xpec_flash_controller_t *str9xpec_info = NULL;
1319 command_print(cmd_ctx, "str9xpec disable_turbo <bank>");
1323 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1326 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1330 str9xpec_info = bank->driver_priv;
1332 chain_pos = str9xpec_info->chain_pos;
1334 dev0 = jtag_get_device(chain_pos);
1336 /* exit turbo mode via TLR */
1337 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_TLR);
1338 jtag_execute_queue();
1340 /* restore previous scan chain */
1341 if( str9xpec_info->devarm ) {
1342 dev0->next = str9xpec_info->devarm;
1344 str9xpec_info->devarm = NULL;