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 .erase_check = str9xpec_erase_check,
91 .protect_check = str9xpec_protect_check,
95 int str9xpec_register_commands(struct command_context_s *cmd_ctx)
97 command_t *str9xpec_cmd = register_command(cmd_ctx, NULL, "str9xpec", NULL, COMMAND_ANY, "str9xpec flash specific commands");
99 register_command(cmd_ctx, str9xpec_cmd, "enable_turbo", str9xpec_handle_flash_enable_turbo_command, COMMAND_EXEC,
100 "enable str9xpec turbo mode");
101 register_command(cmd_ctx, str9xpec_cmd, "disable_turbo", str9xpec_handle_flash_disable_turbo_command, COMMAND_EXEC,
102 "disable str9xpec turbo mode");
103 register_command(cmd_ctx, str9xpec_cmd, "options_cmap", str9xpec_handle_flash_options_cmap_command, COMMAND_EXEC,
104 "configure str9xpec boot sector");
105 register_command(cmd_ctx, str9xpec_cmd, "options_lvdthd", str9xpec_handle_flash_options_lvdthd_command, COMMAND_EXEC,
106 "configure str9xpec lvd threshold");
107 register_command(cmd_ctx, str9xpec_cmd, "options_lvdsel", str9xpec_handle_flash_options_lvdsel_command, COMMAND_EXEC,
108 "configure str9xpec lvd selection");
109 register_command(cmd_ctx, str9xpec_cmd, "options_lvdwarn", str9xpec_handle_flash_options_lvdwarn_command, COMMAND_EXEC,
110 "configure str9xpec lvd warning");
111 register_command(cmd_ctx, str9xpec_cmd, "options_read", str9xpec_handle_flash_options_read_command, COMMAND_EXEC,
112 "read str9xpec options");
113 register_command(cmd_ctx, str9xpec_cmd, "options_write", str9xpec_handle_flash_options_write_command, COMMAND_EXEC,
114 "write str9xpec options");
115 register_command(cmd_ctx, str9xpec_cmd, "lock", str9xpec_handle_flash_lock_command, COMMAND_EXEC,
116 "lock str9xpec device");
117 register_command(cmd_ctx, str9xpec_cmd, "unlock", str9xpec_handle_flash_unlock_command, COMMAND_EXEC,
118 "unlock str9xpec device");
119 register_command(cmd_ctx, str9xpec_cmd, "part_id", str9xpec_handle_part_id_command, COMMAND_EXEC,
120 "print part id of str9xpec flash bank <num>");
125 int str9xpec_set_instr(int chain_pos, u32 new_instr, enum tap_state end_state)
127 jtag_device_t *device = jtag_get_device(chain_pos);
129 if (buf_get_u32(device->cur_instr, 0, device->ir_length) != new_instr)
133 field.device = chain_pos;
134 field.num_bits = device->ir_length;
135 field.out_value = calloc(CEIL(field.num_bits, 8), 1);
136 buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
137 field.out_mask = NULL;
138 field.in_value = NULL;
139 field.in_check_value = NULL;
140 field.in_check_mask = NULL;
141 field.in_handler = NULL;
142 field.in_handler_priv = NULL;
144 jtag_add_ir_scan(1, &field, end_state, NULL);
146 free(field.out_value);
152 u8 str9xpec_isc_status(int chain_pos)
157 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
159 field.device = chain_pos;
161 field.out_value = NULL;
162 field.out_mask = NULL;
163 field.in_value = &status;
164 field.in_check_value = NULL;
165 field.in_check_mask = NULL;
166 field.in_handler = NULL;
167 field.in_handler_priv = NULL;
169 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
170 jtag_execute_queue();
172 DEBUG("status: 0x%2.2x", status);
174 if (status & ISC_STATUS_SECURITY)
175 INFO("Device Security Bit Set");
180 int str9xpec_isc_enable(struct flash_bank_s *bank)
184 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
186 chain_pos = str9xpec_info->chain_pos;
188 if (str9xpec_info->isc_enable)
192 str9xpec_set_instr(chain_pos, ISC_ENABLE, TAP_RTI);
194 /* check ISC status */
195 status = str9xpec_isc_status(chain_pos);
196 if (status & ISC_STATUS_MODE)
198 /* we have entered isc mode */
199 str9xpec_info->isc_enable = 1;
200 DEBUG("ISC_MODE Enabled");
206 int str9xpec_isc_disable(struct flash_bank_s *bank)
210 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
212 chain_pos = str9xpec_info->chain_pos;
214 if (!str9xpec_info->isc_enable)
217 str9xpec_set_instr(chain_pos, ISC_DISABLE, TAP_RTI);
219 /* delay to handle aborts */
222 /* check ISC status */
223 status = str9xpec_isc_status(chain_pos);
224 if (!(status & ISC_STATUS_MODE))
226 /* we have left isc mode */
227 str9xpec_info->isc_enable = 0;
228 DEBUG("ISC_MODE Disabled");
234 int str9xpec_read_config(struct flash_bank_s *bank)
240 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
242 chain_pos = str9xpec_info->chain_pos;
244 DEBUG("ISC_CONFIGURATION");
246 /* execute ISC_CONFIGURATION command */
247 str9xpec_set_instr(chain_pos, ISC_CONFIGURATION, TAP_PI);
249 field.device = chain_pos;
251 field.out_value = NULL;
252 field.out_mask = NULL;
253 field.in_value = str9xpec_info->options;
254 field.in_check_value = NULL;
255 field.in_check_mask = NULL;
256 field.in_handler = NULL;
257 field.in_handler_priv = NULL;
259 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
260 jtag_execute_queue();
262 status = str9xpec_isc_status(chain_pos);
267 int str9xpec_build_block_list(struct flash_bank_s *bank)
269 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
272 int num_sectors = 0, b0_sectors = 0;
283 ERROR("BUG: unknown bank->size encountered");
287 num_sectors = b0_sectors + 4;
289 bank->num_sectors = num_sectors;
290 bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors);
291 str9xpec_info->sector_bits = malloc(sizeof(u32) * num_sectors);
295 for (i = 0; i < b0_sectors; i++)
297 bank->sectors[num_sectors].offset = mem_layout_str9pec[i].sector_start;
298 bank->sectors[num_sectors].size = mem_layout_str9pec[i].sector_size;
299 bank->sectors[num_sectors].is_erased = -1;
300 bank->sectors[num_sectors].is_protected = 1;
301 str9xpec_info->sector_bits[num_sectors++] = mem_layout_str9pec[i].sector_bit;
304 for (i = 8; i < 12; i++)
306 bank->sectors[num_sectors].offset = mem_layout_str9pec[i].sector_start;
307 bank->sectors[num_sectors].size = mem_layout_str9pec[i].sector_size;
308 bank->sectors[num_sectors].is_erased = -1;
309 bank->sectors[num_sectors].is_protected = 1;
310 str9xpec_info->sector_bits[num_sectors++] = mem_layout_str9pec[i].sector_bit;
316 /* flash bank str9x <base> <size> 0 0 <target#>
318 int str9xpec_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
320 str9xpec_flash_controller_t *str9xpec_info;
321 armv4_5_common_t *armv4_5 = NULL;
322 arm7_9_common_t *arm7_9 = NULL;
323 arm_jtag_t *jtag_info = NULL;
327 WARNING("incomplete flash_bank str9x configuration");
328 return ERROR_FLASH_BANK_INVALID;
331 str9xpec_info = malloc(sizeof(str9xpec_flash_controller_t));
332 bank->driver_priv = str9xpec_info;
334 if (bank->base != 0x00000000)
336 WARNING("overriding flash base address for STR91x device with 0x00000000");
337 bank->base = 0x00000000;
340 str9xpec_info->target = get_target_by_num(strtoul(args[5], NULL, 0));
341 if (!str9xpec_info->target)
343 ERROR("no target '%s' configured", args[5]);
347 /* find out jtag position of flash controller
348 * it is always after the arm966 core */
350 armv4_5 = str9xpec_info->target->arch_info;
351 arm7_9 = armv4_5->arch_info;
352 jtag_info = &arm7_9->jtag_info;
354 str9xpec_info->chain_pos = (jtag_info->chain_pos - 1);
355 str9xpec_info->isc_enable = 0;
356 str9xpec_info->devarm = NULL;
358 str9xpec_build_block_list(bank);
360 /* clear option byte register */
361 buf_set_u32(str9xpec_info->options, 0, 64, 0);
366 int str9xpec_blank_check(struct flash_bank_s *bank, int first, int last)
374 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
376 chain_pos = str9xpec_info->chain_pos;
378 if (!str9xpec_info->isc_enable) {
379 str9xpec_isc_enable( bank );
382 if (!str9xpec_info->isc_enable) {
383 return ERROR_FLASH_OPERATION_FAILED;
386 buffer = calloc(CEIL(64, 8), 1);
388 DEBUG("blank check: first_bank: %i, last_bank: %i", first, last);
390 for (i = first; i <= last; i++) {
391 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
394 /* execute ISC_BLANK_CHECK command */
395 str9xpec_set_instr(chain_pos, ISC_BLANK_CHECK, TAP_PI);
397 field.device = chain_pos;
399 field.out_value = buffer;
400 field.out_mask = NULL;
401 field.in_value = NULL;
402 field.in_check_value = NULL;
403 field.in_check_mask = NULL;
404 field.in_handler = NULL;
405 field.in_handler_priv = NULL;
407 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
408 jtag_add_sleep(40000);
410 /* read blank check result */
411 field.device = chain_pos;
413 field.out_value = NULL;
414 field.out_mask = NULL;
415 field.in_value = buffer;
416 field.in_check_value = NULL;
417 field.in_check_mask = NULL;
418 field.in_handler = NULL;
419 field.in_handler_priv = NULL;
421 jtag_add_dr_scan(1, &field, TAP_PI, NULL);
422 jtag_execute_queue();
424 status = str9xpec_isc_status(chain_pos);
426 for (i = first; i <= last; i++)
428 if (buf_get_u32(buffer, str9xpec_info->sector_bits[i], 1))
429 bank->sectors[i].is_erased = 0;
431 bank->sectors[i].is_erased = 1;
436 str9xpec_isc_disable(bank);
438 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
439 return ERROR_FLASH_OPERATION_FAILED;
443 int str9xpec_protect_check(struct flash_bank_s *bank)
448 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
450 status = str9xpec_read_config(bank);
452 for (i = 0; i < bank->num_sectors; i++)
454 if (buf_get_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1))
455 bank->sectors[i].is_protected = 1;
457 bank->sectors[i].is_protected = 0;
460 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
461 return ERROR_FLASH_OPERATION_FAILED;
465 int str9xpec_erase_area(struct flash_bank_s *bank, int first, int last)
473 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
475 chain_pos = str9xpec_info->chain_pos;
477 if (!str9xpec_info->isc_enable) {
478 str9xpec_isc_enable( bank );
481 if (!str9xpec_info->isc_enable) {
482 return ISC_STATUS_ERROR;
485 buffer = calloc(CEIL(64, 8), 1);
487 DEBUG("erase: first_bank: %i, last_bank: %i", first, last);
489 /* last bank: 0xFF signals a full erase (unlock complete device) */
490 /* last bank: 0xFE signals a option byte erase */
493 for (i = 0; i < 64; i++) {
494 buf_set_u32(buffer, i, 1, 1);
497 else if (last == 0xFE)
499 buf_set_u32(buffer, 49, 1, 1);
503 for (i = first; i <= last; i++) {
504 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
510 /* execute ISC_ERASE command */
511 str9xpec_set_instr(chain_pos, ISC_ERASE, TAP_PI);
513 field.device = chain_pos;
515 field.out_value = buffer;
516 field.out_mask = NULL;
517 field.in_value = NULL;
518 field.in_check_value = NULL;
519 field.in_check_mask = NULL;
520 field.in_handler = NULL;
521 field.in_handler_priv = NULL;
523 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
524 jtag_execute_queue();
528 /* wait for erase completion */
529 while (!((status = str9xpec_isc_status(chain_pos)) & ISC_STATUS_BUSY)) {
535 str9xpec_isc_disable(bank);
540 int str9xpec_erase(struct flash_bank_s *bank, int first, int last)
544 status = str9xpec_erase_area(bank, first, last);
546 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
547 return ERROR_FLASH_OPERATION_FAILED;
552 int str9xpec_lock_device(struct flash_bank_s *bank)
557 str9xpec_flash_controller_t *str9xpec_info = NULL;
559 str9xpec_info = bank->driver_priv;
560 chain_pos = str9xpec_info->chain_pos;
562 if (!str9xpec_info->isc_enable) {
563 str9xpec_isc_enable( bank );
566 if (!str9xpec_info->isc_enable) {
567 return ISC_STATUS_ERROR;
570 /* set security address */
571 str9xpec_set_address(bank, 0x80);
573 /* execute ISC_PROGRAM command */
574 str9xpec_set_instr(chain_pos, ISC_PROGRAM_SECURITY, TAP_RTI);
576 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
579 field.device = chain_pos;
581 field.out_value = NULL;
582 field.out_mask = NULL;
583 field.in_value = &status;
584 field.in_check_value = NULL;
585 field.in_check_mask = NULL;
586 field.in_handler = NULL;
587 field.in_handler_priv = NULL;
589 jtag_add_dr_scan(1, &field, -1, NULL);
590 jtag_execute_queue();
592 } while(!(status & ISC_STATUS_BUSY));
594 str9xpec_isc_disable(bank);
599 int str9xpec_unlock_device(struct flash_bank_s *bank)
603 status = str9xpec_erase_area(bank, 0, 255);
608 int str9xpec_protect(struct flash_bank_s *bank, int set, int first, int last)
613 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
615 status = str9xpec_read_config(bank);
617 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
618 return ERROR_FLASH_OPERATION_FAILED;
620 DEBUG("protect: first_bank: %i, last_bank: %i", first, last);
622 /* last bank: 0xFF signals a full device protect */
627 status = str9xpec_lock_device(bank);
631 /* perform full erase to unlock device */
632 status = str9xpec_unlock_device(bank);
637 for (i = first; i <= last; i++)
640 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 1);
642 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 0);
645 status = str9xpec_write_options(bank);
648 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
649 return ERROR_FLASH_OPERATION_FAILED;
654 int str9xpec_set_address(struct flash_bank_s *bank, u8 sector)
658 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
660 chain_pos = str9xpec_info->chain_pos;
662 /* set flash controller address */
663 str9xpec_set_instr(chain_pos, ISC_ADDRESS_SHIFT, TAP_PI);
665 field.device = chain_pos;
667 field.out_value = §or;
668 field.out_mask = NULL;
669 field.in_value = NULL;
670 field.in_check_value = NULL;
671 field.in_check_mask = NULL;
672 field.in_handler = NULL;
673 field.in_handler_priv = NULL;
675 jtag_add_dr_scan(1, &field, -1, NULL);
680 int str9xpec_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
682 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
683 u32 dwords_remaining = (count / 8);
684 u32 bytes_remaining = (count & 0x00000007);
685 u32 bytes_written = 0;
687 u32 check_address = offset;
692 u32 first_sector = 0;
695 chain_pos = str9xpec_info->chain_pos;
697 if (!str9xpec_info->isc_enable) {
698 str9xpec_isc_enable(bank);
701 if (!str9xpec_info->isc_enable) {
702 return ERROR_FLASH_OPERATION_FAILED;
707 WARNING("offset 0x%x breaks required 8-byte alignment", offset);
708 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
711 for (i = 0; i < bank->num_sectors; i++)
713 u32 sec_start = bank->sectors[i].offset;
714 u32 sec_end = sec_start + bank->sectors[i].size;
716 /* check if destination falls within the current sector */
717 if ((check_address >= sec_start) && (check_address < sec_end))
719 /* check if destination ends in the current sector */
720 if (offset + count < sec_end)
721 check_address = offset + count;
723 check_address = sec_end;
726 if ((offset >= sec_start) && (offset < sec_end)){
730 if ((offset + count >= sec_start) && (offset + count < sec_end)){
735 if (check_address != offset + count)
736 return ERROR_FLASH_DST_OUT_OF_BANK;
738 DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
740 scanbuf = calloc(CEIL(64, 8), 1);
742 DEBUG("ISC_PROGRAM");
744 for (i = first_sector; i <= last_sector; i++)
746 str9xpec_set_address(bank, str9xpec_info->sector_bits[i]);
748 dwords_remaining = dwords_remaining < (bank->sectors[i].size/8) ? dwords_remaining : (bank->sectors[i].size/8);
750 while (dwords_remaining > 0)
752 str9xpec_set_instr(chain_pos, ISC_PROGRAM, TAP_PI);
754 field.device = chain_pos;
756 field.out_value = (buffer + bytes_written);
757 field.out_mask = NULL;
758 field.in_value = NULL;
759 field.in_check_value = NULL;
760 field.in_check_mask = NULL;
761 field.in_handler = NULL;
762 field.in_handler_priv = NULL;
764 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
766 /* small delay before polling */
769 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
772 field.device = chain_pos;
774 field.out_value = NULL;
775 field.out_mask = NULL;
776 field.in_value = scanbuf;
777 field.in_check_value = NULL;
778 field.in_check_mask = NULL;
779 field.in_handler = NULL;
780 field.in_handler_priv = NULL;
782 jtag_add_dr_scan(1, &field, -1, NULL);
783 jtag_execute_queue();
785 status = buf_get_u32(scanbuf, 0, 8);
787 } while(!(status & ISC_STATUS_BUSY));
789 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
790 return ERROR_FLASH_OPERATION_FAILED;
792 //if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
793 // return ERROR_FLASH_OPERATION_FAILED;
802 u8 last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
805 while(bytes_remaining > 0)
807 last_dword[i++] = *(buffer + bytes_written);
812 str9xpec_set_instr(chain_pos, ISC_PROGRAM, TAP_PI);
814 field.device = chain_pos;
816 field.out_value = last_dword;
817 field.out_mask = NULL;
818 field.in_value = NULL;
819 field.in_check_value = NULL;
820 field.in_check_mask = NULL;
821 field.in_handler = NULL;
822 field.in_handler_priv = NULL;
824 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
826 /* small delay before polling */
829 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
832 field.device = chain_pos;
834 field.out_value = NULL;
835 field.out_mask = NULL;
836 field.in_value = scanbuf;
837 field.in_check_value = NULL;
838 field.in_check_mask = NULL;
839 field.in_handler = NULL;
840 field.in_handler_priv = NULL;
842 jtag_add_dr_scan(1, &field, -1, NULL);
843 jtag_execute_queue();
845 status = buf_get_u32(scanbuf, 0, 8);
847 } while(!(status & ISC_STATUS_BUSY));
849 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
850 return ERROR_FLASH_OPERATION_FAILED;
852 //if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
853 // return ERROR_FLASH_OPERATION_FAILED;
858 str9xpec_isc_disable(bank);
863 int str9xpec_probe(struct flash_bank_s *bank)
868 int str9xpec_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
875 str9xpec_flash_controller_t *str9xpec_info = NULL;
879 command_print(cmd_ctx, "usage: str9xpec part_id <num>");
883 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
886 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
890 str9xpec_info = bank->driver_priv;
891 chain_pos = str9xpec_info->chain_pos;
893 buffer = calloc(CEIL(32, 8), 1);
895 str9xpec_set_instr(chain_pos, ISC_IDCODE, TAP_PI);
897 field.device = chain_pos;
899 field.out_value = NULL;
900 field.out_mask = NULL;
901 field.in_value = buffer;
902 field.in_check_value = NULL;
903 field.in_check_mask = NULL;
904 field.in_handler = NULL;
905 field.in_handler_priv = NULL;
907 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
908 jtag_execute_queue();
910 idcode = buf_get_u32(buffer, 0, 32);
912 command_print(cmd_ctx, "str9xpec part id: 0x%8.8x", idcode);
919 int str9xpec_erase_check(struct flash_bank_s *bank)
921 return str9xpec_blank_check(bank, 0, bank->num_sectors - 1);
924 int str9xpec_info(struct flash_bank_s *bank, char *buf, int buf_size)
926 snprintf(buf, buf_size, "str9xpec flash driver info" );
930 int str9xpec_handle_flash_options_read_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
934 str9xpec_flash_controller_t *str9xpec_info = NULL;
938 command_print(cmd_ctx, "str9xpec options_read <bank>");
942 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
945 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
949 str9xpec_info = bank->driver_priv;
951 status = str9xpec_read_config(bank);
953 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
954 return ERROR_FLASH_OPERATION_FAILED;
957 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1))
958 command_print(cmd_ctx, "CS Map: bank1");
960 command_print(cmd_ctx, "CS Map: bank0");
963 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1))
964 command_print(cmd_ctx, "OTP Lock: OTP Locked");
966 command_print(cmd_ctx, "OTP Lock: OTP Unlocked");
969 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1))
970 command_print(cmd_ctx, "LVD Threshold: 2.7v");
972 command_print(cmd_ctx, "LVD Threshold: 2.4v");
974 /* LVD reset warning */
975 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1))
976 command_print(cmd_ctx, "LVD Reset Warning: VDD or VDDQ Inputs");
978 command_print(cmd_ctx, "LVD Reset Warning: VDD Input Only");
980 /* LVD reset select */
981 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1))
982 command_print(cmd_ctx, "LVD Reset Selection: VDD or VDDQ Inputs");
984 command_print(cmd_ctx, "LVD Reset Selection: VDD Input Only");
989 int str9xpec_write_options(struct flash_bank_s *bank)
994 str9xpec_flash_controller_t *str9xpec_info = NULL;
996 str9xpec_info = bank->driver_priv;
997 chain_pos = str9xpec_info->chain_pos;
999 /* erase config options first */
1000 str9xpec_erase_area( bank, 0xFE, 0xFE );
1002 if (!str9xpec_info->isc_enable) {
1003 str9xpec_isc_enable( bank );
1006 if (!str9xpec_info->isc_enable) {
1007 return ISC_STATUS_ERROR;
1010 /* according to data 64th bit has to be set */
1011 buf_set_u32(str9xpec_info->options, 63, 1, 1);
1013 /* set option byte address */
1014 str9xpec_set_address(bank, 0x50);
1016 /* execute ISC_PROGRAM command */
1017 str9xpec_set_instr(chain_pos, ISC_PROGRAM, TAP_PI);
1019 field.device = chain_pos;
1020 field.num_bits = 64;
1021 field.out_value = str9xpec_info->options;
1022 field.out_mask = NULL;
1023 field.in_value = NULL;
1024 field.in_check_value = NULL;
1025 field.in_check_mask = NULL;
1026 field.in_handler = NULL;
1027 field.in_handler_priv = NULL;
1029 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
1031 /* small delay before polling */
1034 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
1037 field.device = chain_pos;
1039 field.out_value = NULL;
1040 field.out_mask = NULL;
1041 field.in_value = &status;
1042 field.in_check_value = NULL;
1043 field.in_check_mask = NULL;
1044 field.in_handler = NULL;
1045 field.in_handler_priv = NULL;
1047 jtag_add_dr_scan(1, &field, -1, NULL);
1048 jtag_execute_queue();
1050 } while(!(status & ISC_STATUS_BUSY));
1052 str9xpec_isc_disable(bank);
1057 int str9xpec_handle_flash_options_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1064 command_print(cmd_ctx, "str9xpec options_write <bank>");
1068 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1071 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1075 status = str9xpec_write_options(bank);
1077 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1078 return ERROR_FLASH_OPERATION_FAILED;
1083 int str9xpec_handle_flash_options_cmap_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1086 str9xpec_flash_controller_t *str9xpec_info = NULL;
1090 command_print(cmd_ctx, "str9xpec options_cmap <bank> <bank0|bank1>");
1094 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1097 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1101 str9xpec_info = bank->driver_priv;
1103 if (strcmp(args[1], "bank1") == 0)
1105 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 1);
1109 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0);
1115 int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1118 str9xpec_flash_controller_t *str9xpec_info = NULL;
1122 command_print(cmd_ctx, "str9xpec options_lvdthd <bank> <2.4v|2.7v>");
1126 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1129 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1133 str9xpec_info = bank->driver_priv;
1135 if (strcmp(args[1], "2.7v") == 0)
1137 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 1);
1141 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0);
1147 int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1150 str9xpec_flash_controller_t *str9xpec_info = NULL;
1154 command_print(cmd_ctx, "str9xpec options_lvdsel <bank> <vdd|vdd_vddq>");
1158 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1161 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1165 str9xpec_info = bank->driver_priv;
1167 if (strcmp(args[1], "vdd_vddq") == 0)
1169 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 1);
1173 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0);
1179 int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1182 str9xpec_flash_controller_t *str9xpec_info = NULL;
1186 command_print(cmd_ctx, "str9xpec options_lvdwarn <bank> <vdd|vdd_vddq>");
1190 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1193 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1197 str9xpec_info = bank->driver_priv;
1199 if (strcmp(args[1], "vdd_vddq") == 0)
1201 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 1);
1205 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0);
1211 int str9xpec_handle_flash_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1218 command_print(cmd_ctx, "str9xpec lock <bank>");
1222 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1225 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1229 status = str9xpec_lock_device(bank);
1231 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1232 return ERROR_FLASH_OPERATION_FAILED;
1237 int str9xpec_handle_flash_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1244 command_print(cmd_ctx, "str9xpec unlock <bank>");
1248 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1251 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1255 status = str9xpec_unlock_device(bank);
1257 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1258 return ERROR_FLASH_OPERATION_FAILED;
1263 int str9xpec_handle_flash_enable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1267 jtag_device_t* dev0;
1268 jtag_device_t* dev2;
1269 str9xpec_flash_controller_t *str9xpec_info = NULL;
1273 command_print(cmd_ctx, "str9xpec enable_turbo <bank>");
1277 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1280 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1284 str9xpec_info = bank->driver_priv;
1286 chain_pos = str9xpec_info->chain_pos;
1288 /* remove arm core from chain - enter turbo mode */
1290 str9xpec_set_instr(chain_pos+2, 0xD, TAP_RTI);
1291 jtag_execute_queue();
1293 /* modify scan chain - str9 core has been removed */
1294 dev0 = jtag_get_device(chain_pos);
1295 str9xpec_info->devarm = jtag_get_device(chain_pos+1);
1296 dev2 = jtag_get_device(chain_pos+2);
1303 int str9xpec_handle_flash_disable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1307 jtag_device_t* dev0;
1308 str9xpec_flash_controller_t *str9xpec_info = NULL;
1312 command_print(cmd_ctx, "str9xpec disable_turbo <bank>");
1316 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1319 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1323 str9xpec_info = bank->driver_priv;
1325 chain_pos = str9xpec_info->chain_pos;
1327 dev0 = jtag_get_device(chain_pos);
1329 /* exit turbo mode via TLR */
1330 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_TLR);
1331 jtag_execute_queue();
1333 /* restore previous scan chain */
1334 if( str9xpec_info->devarm ) {
1335 dev0->next = str9xpec_info->devarm;