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 //jtag_device_t* dev0;
604 //jtag_device_t* dev1;
605 //jtag_device_t* dev2;
607 //str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
609 //chain_pos = str9xpec_info->chain_pos;
611 /* remove arm core from chain - enter turbo mode */
613 //str9xpec_set_instr(chain_pos+2, 0xD, TAP_RTI);
614 //jtag_execute_queue();
616 /* modify scan chain - arm9 has been removed */
617 //dev0 = jtag_get_device(chain_pos);
618 //dev1 = jtag_get_device(chain_pos+1);
619 //dev2 = jtag_get_device(chain_pos+2);
621 //jtag_num_devices--;
623 status = str9xpec_erase_area(bank, 0, 255);
625 /* exit turbo mode via TLR */
626 //str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_TLR);
627 //jtag_execute_queue();
629 /* restore previous scan chain */
631 //jtag_num_devices++;
636 int str9xpec_protect(struct flash_bank_s *bank, int set, int first, int last)
641 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
643 status = str9xpec_read_config(bank);
645 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
646 return ERROR_FLASH_OPERATION_FAILED;
648 DEBUG("protect: first_bank: %i, last_bank: %i", first, last);
650 /* last bank: 0xFF signals a full device protect */
655 status = str9xpec_lock_device(bank);
659 /* perform full erase to unlock device */
660 status = str9xpec_unlock_device(bank);
665 for (i = first; i <= last; i++)
668 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 1);
670 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 0);
673 status = str9xpec_write_options(bank);
676 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
677 return ERROR_FLASH_OPERATION_FAILED;
682 int str9xpec_set_address(struct flash_bank_s *bank, u8 sector)
686 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
688 chain_pos = str9xpec_info->chain_pos;
690 /* set flash controller address */
691 str9xpec_set_instr(chain_pos, ISC_ADDRESS_SHIFT, TAP_PI);
693 field.device = chain_pos;
695 field.out_value = §or;
696 field.out_mask = NULL;
697 field.in_value = NULL;
698 field.in_check_value = NULL;
699 field.in_check_mask = NULL;
700 field.in_handler = NULL;
701 field.in_handler_priv = NULL;
703 jtag_add_dr_scan(1, &field, -1, NULL);
708 int str9xpec_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
710 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
711 u32 dwords_remaining = (count / 8);
712 u32 bytes_remaining = (count & 0x00000007);
713 u32 bytes_written = 0;
715 u32 check_address = offset;
720 u32 first_sector = 0;
723 chain_pos = str9xpec_info->chain_pos;
725 if (!str9xpec_info->isc_enable) {
726 str9xpec_isc_enable(bank);
729 if (!str9xpec_info->isc_enable) {
730 return ERROR_FLASH_OPERATION_FAILED;
735 WARNING("offset 0x%x breaks required 8-byte alignment", offset);
736 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
739 for (i = 0; i < bank->num_sectors; i++)
741 u32 sec_start = bank->sectors[i].offset;
742 u32 sec_end = sec_start + bank->sectors[i].size;
744 /* check if destination falls within the current sector */
745 if ((check_address >= sec_start) && (check_address < sec_end))
747 /* check if destination ends in the current sector */
748 if (offset + count < sec_end)
749 check_address = offset + count;
751 check_address = sec_end;
754 if ((offset >= sec_start) && (offset < sec_end)){
758 if ((offset + count >= sec_start) && (offset + count < sec_end)){
763 if (check_address != offset + count)
764 return ERROR_FLASH_DST_OUT_OF_BANK;
766 DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
768 scanbuf = calloc(CEIL(64, 8), 1);
770 DEBUG("ISC_PROGRAM");
772 for (i = first_sector; i <= last_sector; i++)
774 str9xpec_set_address(bank, str9xpec_info->sector_bits[i]);
776 dwords_remaining = dwords_remaining < (bank->sectors[i].size/8) ? dwords_remaining : (bank->sectors[i].size/8);
778 while (dwords_remaining > 0)
780 str9xpec_set_instr(chain_pos, ISC_PROGRAM, TAP_PI);
782 field.device = chain_pos;
784 field.out_value = (buffer + bytes_written);
785 field.out_mask = NULL;
786 field.in_value = NULL;
787 field.in_check_value = NULL;
788 field.in_check_mask = NULL;
789 field.in_handler = NULL;
790 field.in_handler_priv = NULL;
792 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
794 /* small delay before polling */
797 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
800 field.device = chain_pos;
802 field.out_value = NULL;
803 field.out_mask = NULL;
804 field.in_value = scanbuf;
805 field.in_check_value = NULL;
806 field.in_check_mask = NULL;
807 field.in_handler = NULL;
808 field.in_handler_priv = NULL;
810 jtag_add_dr_scan(1, &field, -1, NULL);
811 jtag_execute_queue();
813 status = buf_get_u32(scanbuf, 0, 8);
815 } while(!(status & ISC_STATUS_BUSY));
817 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
818 return ERROR_FLASH_OPERATION_FAILED;
820 //if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
821 // return ERROR_FLASH_OPERATION_FAILED;
830 u8 last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
833 while(bytes_remaining > 0)
835 last_dword[i++] = *(buffer + bytes_written);
840 str9xpec_set_instr(chain_pos, ISC_PROGRAM, TAP_PI);
842 field.device = chain_pos;
844 field.out_value = last_dword;
845 field.out_mask = NULL;
846 field.in_value = NULL;
847 field.in_check_value = NULL;
848 field.in_check_mask = NULL;
849 field.in_handler = NULL;
850 field.in_handler_priv = NULL;
852 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
854 /* small delay before polling */
857 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
860 field.device = chain_pos;
862 field.out_value = NULL;
863 field.out_mask = NULL;
864 field.in_value = scanbuf;
865 field.in_check_value = NULL;
866 field.in_check_mask = NULL;
867 field.in_handler = NULL;
868 field.in_handler_priv = NULL;
870 jtag_add_dr_scan(1, &field, -1, NULL);
871 jtag_execute_queue();
873 status = buf_get_u32(scanbuf, 0, 8);
875 } while(!(status & ISC_STATUS_BUSY));
877 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
878 return ERROR_FLASH_OPERATION_FAILED;
880 //if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
881 // return ERROR_FLASH_OPERATION_FAILED;
886 str9xpec_isc_disable(bank);
891 int str9xpec_probe(struct flash_bank_s *bank)
896 int str9xpec_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
903 str9xpec_flash_controller_t *str9xpec_info = NULL;
907 command_print(cmd_ctx, "usage: str9xpec part_id <num>");
911 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
914 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
918 str9xpec_info = bank->driver_priv;
919 chain_pos = str9xpec_info->chain_pos;
921 buffer = calloc(CEIL(32, 8), 1);
923 str9xpec_set_instr(chain_pos, ISC_IDCODE, TAP_PI);
925 field.device = chain_pos;
927 field.out_value = NULL;
928 field.out_mask = NULL;
929 field.in_value = buffer;
930 field.in_check_value = NULL;
931 field.in_check_mask = NULL;
932 field.in_handler = NULL;
933 field.in_handler_priv = NULL;
935 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
936 jtag_execute_queue();
938 idcode = buf_get_u32(buffer, 0, 32);
940 command_print(cmd_ctx, "str9xpec part id: 0x%8.8x", idcode);
947 int str9xpec_erase_check(struct flash_bank_s *bank)
949 return str9xpec_blank_check(bank, 0, bank->num_sectors - 1);
952 int str9xpec_info(struct flash_bank_s *bank, char *buf, int buf_size)
954 snprintf(buf, buf_size, "str9xpec flash driver info" );
958 int str9xpec_handle_flash_options_read_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
962 str9xpec_flash_controller_t *str9xpec_info = NULL;
966 command_print(cmd_ctx, "str9xpec options_read <bank>");
970 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
973 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
977 str9xpec_info = bank->driver_priv;
979 status = str9xpec_read_config(bank);
981 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
982 return ERROR_FLASH_OPERATION_FAILED;
985 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1))
986 command_print(cmd_ctx, "CS Map: bank1");
988 command_print(cmd_ctx, "CS Map: bank0");
991 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1))
992 command_print(cmd_ctx, "OTP Lock: OTP Locked");
994 command_print(cmd_ctx, "OTP Lock: OTP Unlocked");
997 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1))
998 command_print(cmd_ctx, "LVD Threshold: 2.7v");
1000 command_print(cmd_ctx, "LVD Threshold: 2.4v");
1002 /* LVD reset warning */
1003 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1))
1004 command_print(cmd_ctx, "LVD Reset Warning: VDD or VDDQ Inputs");
1006 command_print(cmd_ctx, "LVD Reset Warning: VDD Input Only");
1008 /* LVD reset select */
1009 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1))
1010 command_print(cmd_ctx, "LVD Reset Selection: VDD or VDDQ Inputs");
1012 command_print(cmd_ctx, "LVD Reset Selection: VDD Input Only");
1017 int str9xpec_write_options(struct flash_bank_s *bank)
1022 str9xpec_flash_controller_t *str9xpec_info = NULL;
1024 str9xpec_info = bank->driver_priv;
1025 chain_pos = str9xpec_info->chain_pos;
1027 /* erase config options first */
1028 str9xpec_erase_area( bank, 0xFE, 0xFE );
1030 if (!str9xpec_info->isc_enable) {
1031 str9xpec_isc_enable( bank );
1034 if (!str9xpec_info->isc_enable) {
1035 return ISC_STATUS_ERROR;
1038 /* according to data 64th bit has to be set */
1039 buf_set_u32(str9xpec_info->options, 63, 1, 1);
1041 /* set option byte address */
1042 str9xpec_set_address(bank, 0x50);
1044 /* execute ISC_PROGRAM command */
1045 str9xpec_set_instr(chain_pos, ISC_PROGRAM, TAP_PI);
1047 field.device = chain_pos;
1048 field.num_bits = 64;
1049 field.out_value = str9xpec_info->options;
1050 field.out_mask = NULL;
1051 field.in_value = NULL;
1052 field.in_check_value = NULL;
1053 field.in_check_mask = NULL;
1054 field.in_handler = NULL;
1055 field.in_handler_priv = NULL;
1057 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
1059 /* small delay before polling */
1062 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
1065 field.device = chain_pos;
1067 field.out_value = NULL;
1068 field.out_mask = NULL;
1069 field.in_value = &status;
1070 field.in_check_value = NULL;
1071 field.in_check_mask = NULL;
1072 field.in_handler = NULL;
1073 field.in_handler_priv = NULL;
1075 jtag_add_dr_scan(1, &field, -1, NULL);
1076 jtag_execute_queue();
1078 } while(!(status & ISC_STATUS_BUSY));
1080 str9xpec_isc_disable(bank);
1085 int str9xpec_handle_flash_options_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1092 command_print(cmd_ctx, "str9xpec options_write <bank>");
1096 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1099 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1103 status = str9xpec_write_options(bank);
1105 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1106 return ERROR_FLASH_OPERATION_FAILED;
1111 int str9xpec_handle_flash_options_cmap_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1114 str9xpec_flash_controller_t *str9xpec_info = NULL;
1118 command_print(cmd_ctx, "str9xpec options_cmap <bank> <bank0|bank1>");
1122 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1125 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1129 str9xpec_info = bank->driver_priv;
1131 if (stricmp(args[1], "bank1") == 0)
1133 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 1);
1137 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0);
1143 int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1146 str9xpec_flash_controller_t *str9xpec_info = NULL;
1150 command_print(cmd_ctx, "str9xpec options_lvdthd <bank> <2.4v|2.7v>");
1154 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1157 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1161 str9xpec_info = bank->driver_priv;
1163 if (stricmp(args[1], "2.7v") == 0)
1165 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 1);
1169 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0);
1175 int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1178 str9xpec_flash_controller_t *str9xpec_info = NULL;
1182 command_print(cmd_ctx, "str9xpec options_lvdsel <bank> <vdd|vdd_vddq>");
1186 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1189 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1193 str9xpec_info = bank->driver_priv;
1195 if (stricmp(args[1], "vdd_vddq") == 0)
1197 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 1);
1201 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0);
1207 int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1210 str9xpec_flash_controller_t *str9xpec_info = NULL;
1214 command_print(cmd_ctx, "str9xpec options_lvdwarn <bank> <vdd|vdd_vddq>");
1218 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1221 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1225 str9xpec_info = bank->driver_priv;
1227 if (stricmp(args[1], "vdd_vddq") == 0)
1229 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 1);
1233 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0);
1239 int str9xpec_handle_flash_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1246 command_print(cmd_ctx, "str9xpec lock <bank>");
1250 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1253 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1257 status = str9xpec_lock_device(bank);
1259 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1260 return ERROR_FLASH_OPERATION_FAILED;
1265 int str9xpec_handle_flash_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1272 command_print(cmd_ctx, "str9xpec unlock <bank>");
1276 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1279 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1283 status = str9xpec_unlock_device(bank);
1285 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1286 return ERROR_FLASH_OPERATION_FAILED;
1291 int str9xpec_handle_flash_enable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1295 jtag_device_t* dev0;
1296 jtag_device_t* dev2;
1297 str9xpec_flash_controller_t *str9xpec_info = NULL;
1301 command_print(cmd_ctx, "str9xpec enable_turbo <bank>");
1305 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1308 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1312 str9xpec_info = bank->driver_priv;
1314 chain_pos = str9xpec_info->chain_pos;
1316 /* remove arm core from chain - enter turbo mode */
1318 str9xpec_set_instr(chain_pos+2, 0xD, TAP_RTI);
1319 jtag_execute_queue();
1321 /* modify scan chain - str9 core has been removed */
1322 dev0 = jtag_get_device(chain_pos);
1323 str9xpec_info->devarm = jtag_get_device(chain_pos+1);
1324 dev2 = jtag_get_device(chain_pos+2);
1331 int str9xpec_handle_flash_disable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1335 jtag_device_t* dev0;
1336 str9xpec_flash_controller_t *str9xpec_info = NULL;
1340 command_print(cmd_ctx, "str9xpec disable_turbo <bank>");
1344 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1347 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1351 str9xpec_info = bank->driver_priv;
1353 chain_pos = str9xpec_info->chain_pos;
1355 dev0 = jtag_get_device(chain_pos);
1357 /* exit turbo mode via TLR */
1358 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_TLR);
1359 jtag_execute_queue();
1361 /* restore previous scan chain */
1362 if( str9xpec_info->devarm ) {
1363 dev0->next = str9xpec_info->devarm;