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 /* find out jtag position of flash controller
341 * it is always after the arm966 core */
343 armv4_5 = bank->target->arch_info;
344 arm7_9 = armv4_5->arch_info;
345 jtag_info = &arm7_9->jtag_info;
347 str9xpec_info->chain_pos = (jtag_info->chain_pos - 1);
348 str9xpec_info->isc_enable = 0;
349 str9xpec_info->devarm = NULL;
351 str9xpec_build_block_list(bank);
353 /* clear option byte register */
354 buf_set_u32(str9xpec_info->options, 0, 64, 0);
359 int str9xpec_blank_check(struct flash_bank_s *bank, int first, int last)
367 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
369 chain_pos = str9xpec_info->chain_pos;
371 if (!str9xpec_info->isc_enable) {
372 str9xpec_isc_enable( bank );
375 if (!str9xpec_info->isc_enable) {
376 return ERROR_FLASH_OPERATION_FAILED;
379 buffer = calloc(CEIL(64, 8), 1);
381 DEBUG("blank check: first_bank: %i, last_bank: %i", first, last);
383 for (i = first; i <= last; i++) {
384 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
387 /* execute ISC_BLANK_CHECK command */
388 str9xpec_set_instr(chain_pos, ISC_BLANK_CHECK, TAP_PI);
390 field.device = chain_pos;
392 field.out_value = buffer;
393 field.out_mask = NULL;
394 field.in_value = NULL;
395 field.in_check_value = NULL;
396 field.in_check_mask = NULL;
397 field.in_handler = NULL;
398 field.in_handler_priv = NULL;
400 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
401 jtag_add_sleep(40000);
403 /* read blank check result */
404 field.device = chain_pos;
406 field.out_value = NULL;
407 field.out_mask = NULL;
408 field.in_value = buffer;
409 field.in_check_value = NULL;
410 field.in_check_mask = NULL;
411 field.in_handler = NULL;
412 field.in_handler_priv = NULL;
414 jtag_add_dr_scan(1, &field, TAP_PI, NULL);
415 jtag_execute_queue();
417 status = str9xpec_isc_status(chain_pos);
419 for (i = first; i <= last; i++)
421 if (buf_get_u32(buffer, str9xpec_info->sector_bits[i], 1))
422 bank->sectors[i].is_erased = 0;
424 bank->sectors[i].is_erased = 1;
429 str9xpec_isc_disable(bank);
431 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
432 return ERROR_FLASH_OPERATION_FAILED;
436 int str9xpec_protect_check(struct flash_bank_s *bank)
441 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
443 status = str9xpec_read_config(bank);
445 for (i = 0; i < bank->num_sectors; i++)
447 if (buf_get_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1))
448 bank->sectors[i].is_protected = 1;
450 bank->sectors[i].is_protected = 0;
453 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
454 return ERROR_FLASH_OPERATION_FAILED;
458 int str9xpec_erase_area(struct flash_bank_s *bank, int first, int last)
466 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
468 chain_pos = str9xpec_info->chain_pos;
470 if (!str9xpec_info->isc_enable) {
471 str9xpec_isc_enable( bank );
474 if (!str9xpec_info->isc_enable) {
475 return ISC_STATUS_ERROR;
478 buffer = calloc(CEIL(64, 8), 1);
480 DEBUG("erase: first_bank: %i, last_bank: %i", first, last);
482 /* last bank: 0xFF signals a full erase (unlock complete device) */
483 /* last bank: 0xFE signals a option byte erase */
486 for (i = 0; i < 64; i++) {
487 buf_set_u32(buffer, i, 1, 1);
490 else if (last == 0xFE)
492 buf_set_u32(buffer, 49, 1, 1);
496 for (i = first; i <= last; i++) {
497 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
503 /* execute ISC_ERASE command */
504 str9xpec_set_instr(chain_pos, ISC_ERASE, TAP_PI);
506 field.device = chain_pos;
508 field.out_value = buffer;
509 field.out_mask = NULL;
510 field.in_value = NULL;
511 field.in_check_value = NULL;
512 field.in_check_mask = NULL;
513 field.in_handler = NULL;
514 field.in_handler_priv = NULL;
516 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
517 jtag_execute_queue();
521 /* wait for erase completion */
522 while (!((status = str9xpec_isc_status(chain_pos)) & ISC_STATUS_BUSY)) {
528 str9xpec_isc_disable(bank);
533 int str9xpec_erase(struct flash_bank_s *bank, int first, int last)
537 status = str9xpec_erase_area(bank, first, last);
539 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
540 return ERROR_FLASH_OPERATION_FAILED;
545 int str9xpec_lock_device(struct flash_bank_s *bank)
550 str9xpec_flash_controller_t *str9xpec_info = NULL;
552 str9xpec_info = bank->driver_priv;
553 chain_pos = str9xpec_info->chain_pos;
555 if (!str9xpec_info->isc_enable) {
556 str9xpec_isc_enable( bank );
559 if (!str9xpec_info->isc_enable) {
560 return ISC_STATUS_ERROR;
563 /* set security address */
564 str9xpec_set_address(bank, 0x80);
566 /* execute ISC_PROGRAM command */
567 str9xpec_set_instr(chain_pos, ISC_PROGRAM_SECURITY, TAP_RTI);
569 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
572 field.device = chain_pos;
574 field.out_value = NULL;
575 field.out_mask = NULL;
576 field.in_value = &status;
577 field.in_check_value = NULL;
578 field.in_check_mask = NULL;
579 field.in_handler = NULL;
580 field.in_handler_priv = NULL;
582 jtag_add_dr_scan(1, &field, -1, NULL);
583 jtag_execute_queue();
585 } while(!(status & ISC_STATUS_BUSY));
587 str9xpec_isc_disable(bank);
592 int str9xpec_unlock_device(struct flash_bank_s *bank)
596 status = str9xpec_erase_area(bank, 0, 255);
601 int str9xpec_protect(struct flash_bank_s *bank, int set, int first, int last)
606 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
608 status = str9xpec_read_config(bank);
610 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
611 return ERROR_FLASH_OPERATION_FAILED;
613 DEBUG("protect: first_bank: %i, last_bank: %i", first, last);
615 /* last bank: 0xFF signals a full device protect */
620 status = str9xpec_lock_device(bank);
624 /* perform full erase to unlock device */
625 status = str9xpec_unlock_device(bank);
630 for (i = first; i <= last; i++)
633 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 1);
635 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 0);
638 status = str9xpec_write_options(bank);
641 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
642 return ERROR_FLASH_OPERATION_FAILED;
647 int str9xpec_set_address(struct flash_bank_s *bank, u8 sector)
651 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
653 chain_pos = str9xpec_info->chain_pos;
655 /* set flash controller address */
656 str9xpec_set_instr(chain_pos, ISC_ADDRESS_SHIFT, TAP_PI);
658 field.device = chain_pos;
660 field.out_value = §or;
661 field.out_mask = NULL;
662 field.in_value = NULL;
663 field.in_check_value = NULL;
664 field.in_check_mask = NULL;
665 field.in_handler = NULL;
666 field.in_handler_priv = NULL;
668 jtag_add_dr_scan(1, &field, -1, NULL);
673 int str9xpec_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
675 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
676 u32 dwords_remaining = (count / 8);
677 u32 bytes_remaining = (count & 0x00000007);
678 u32 bytes_written = 0;
680 u32 check_address = offset;
685 u32 first_sector = 0;
688 chain_pos = str9xpec_info->chain_pos;
690 if (!str9xpec_info->isc_enable) {
691 str9xpec_isc_enable(bank);
694 if (!str9xpec_info->isc_enable) {
695 return ERROR_FLASH_OPERATION_FAILED;
700 WARNING("offset 0x%x breaks required 8-byte alignment", offset);
701 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
704 for (i = 0; i < bank->num_sectors; i++)
706 u32 sec_start = bank->sectors[i].offset;
707 u32 sec_end = sec_start + bank->sectors[i].size;
709 /* check if destination falls within the current sector */
710 if ((check_address >= sec_start) && (check_address < sec_end))
712 /* check if destination ends in the current sector */
713 if (offset + count < sec_end)
714 check_address = offset + count;
716 check_address = sec_end;
719 if ((offset >= sec_start) && (offset < sec_end)){
723 if ((offset + count >= sec_start) && (offset + count < sec_end)){
728 if (check_address != offset + count)
729 return ERROR_FLASH_DST_OUT_OF_BANK;
731 DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
733 scanbuf = calloc(CEIL(64, 8), 1);
735 DEBUG("ISC_PROGRAM");
737 for (i = first_sector; i <= last_sector; i++)
739 str9xpec_set_address(bank, str9xpec_info->sector_bits[i]);
741 dwords_remaining = dwords_remaining < (bank->sectors[i].size/8) ? dwords_remaining : (bank->sectors[i].size/8);
743 while (dwords_remaining > 0)
745 str9xpec_set_instr(chain_pos, ISC_PROGRAM, TAP_PI);
747 field.device = chain_pos;
749 field.out_value = (buffer + bytes_written);
750 field.out_mask = NULL;
751 field.in_value = NULL;
752 field.in_check_value = NULL;
753 field.in_check_mask = NULL;
754 field.in_handler = NULL;
755 field.in_handler_priv = NULL;
757 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
759 /* small delay before polling */
762 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
765 field.device = chain_pos;
767 field.out_value = NULL;
768 field.out_mask = NULL;
769 field.in_value = scanbuf;
770 field.in_check_value = NULL;
771 field.in_check_mask = NULL;
772 field.in_handler = NULL;
773 field.in_handler_priv = NULL;
775 jtag_add_dr_scan(1, &field, -1, NULL);
776 jtag_execute_queue();
778 status = buf_get_u32(scanbuf, 0, 8);
780 } while(!(status & ISC_STATUS_BUSY));
782 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
783 return ERROR_FLASH_OPERATION_FAILED;
785 //if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
786 // return ERROR_FLASH_OPERATION_FAILED;
795 u8 last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
798 while(bytes_remaining > 0)
800 last_dword[i++] = *(buffer + bytes_written);
805 str9xpec_set_instr(chain_pos, ISC_PROGRAM, TAP_PI);
807 field.device = chain_pos;
809 field.out_value = last_dword;
810 field.out_mask = NULL;
811 field.in_value = NULL;
812 field.in_check_value = NULL;
813 field.in_check_mask = NULL;
814 field.in_handler = NULL;
815 field.in_handler_priv = NULL;
817 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
819 /* small delay before polling */
822 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
825 field.device = chain_pos;
827 field.out_value = NULL;
828 field.out_mask = NULL;
829 field.in_value = scanbuf;
830 field.in_check_value = NULL;
831 field.in_check_mask = NULL;
832 field.in_handler = NULL;
833 field.in_handler_priv = NULL;
835 jtag_add_dr_scan(1, &field, -1, NULL);
836 jtag_execute_queue();
838 status = buf_get_u32(scanbuf, 0, 8);
840 } while(!(status & ISC_STATUS_BUSY));
842 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
843 return ERROR_FLASH_OPERATION_FAILED;
845 //if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
846 // return ERROR_FLASH_OPERATION_FAILED;
851 str9xpec_isc_disable(bank);
856 int str9xpec_probe(struct flash_bank_s *bank)
861 int str9xpec_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
868 str9xpec_flash_controller_t *str9xpec_info = NULL;
872 command_print(cmd_ctx, "usage: str9xpec part_id <num>");
876 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
879 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
883 str9xpec_info = bank->driver_priv;
884 chain_pos = str9xpec_info->chain_pos;
886 buffer = calloc(CEIL(32, 8), 1);
888 str9xpec_set_instr(chain_pos, ISC_IDCODE, TAP_PI);
890 field.device = chain_pos;
892 field.out_value = NULL;
893 field.out_mask = NULL;
894 field.in_value = buffer;
895 field.in_check_value = NULL;
896 field.in_check_mask = NULL;
897 field.in_handler = NULL;
898 field.in_handler_priv = NULL;
900 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
901 jtag_execute_queue();
903 idcode = buf_get_u32(buffer, 0, 32);
905 command_print(cmd_ctx, "str9xpec part id: 0x%8.8x", idcode);
912 int str9xpec_erase_check(struct flash_bank_s *bank)
914 return str9xpec_blank_check(bank, 0, bank->num_sectors - 1);
917 int str9xpec_info(struct flash_bank_s *bank, char *buf, int buf_size)
919 snprintf(buf, buf_size, "str9xpec flash driver info" );
923 int str9xpec_handle_flash_options_read_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
927 str9xpec_flash_controller_t *str9xpec_info = NULL;
931 command_print(cmd_ctx, "str9xpec options_read <bank>");
935 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
938 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
942 str9xpec_info = bank->driver_priv;
944 status = str9xpec_read_config(bank);
946 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
947 return ERROR_FLASH_OPERATION_FAILED;
950 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1))
951 command_print(cmd_ctx, "CS Map: bank1");
953 command_print(cmd_ctx, "CS Map: bank0");
956 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1))
957 command_print(cmd_ctx, "OTP Lock: OTP Locked");
959 command_print(cmd_ctx, "OTP Lock: OTP Unlocked");
962 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1))
963 command_print(cmd_ctx, "LVD Threshold: 2.7v");
965 command_print(cmd_ctx, "LVD Threshold: 2.4v");
967 /* LVD reset warning */
968 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1))
969 command_print(cmd_ctx, "LVD Reset Warning: VDD or VDDQ Inputs");
971 command_print(cmd_ctx, "LVD Reset Warning: VDD Input Only");
973 /* LVD reset select */
974 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1))
975 command_print(cmd_ctx, "LVD Reset Selection: VDD or VDDQ Inputs");
977 command_print(cmd_ctx, "LVD Reset Selection: VDD Input Only");
982 int str9xpec_write_options(struct flash_bank_s *bank)
987 str9xpec_flash_controller_t *str9xpec_info = NULL;
989 str9xpec_info = bank->driver_priv;
990 chain_pos = str9xpec_info->chain_pos;
992 /* erase config options first */
993 str9xpec_erase_area( bank, 0xFE, 0xFE );
995 if (!str9xpec_info->isc_enable) {
996 str9xpec_isc_enable( bank );
999 if (!str9xpec_info->isc_enable) {
1000 return ISC_STATUS_ERROR;
1003 /* according to data 64th bit has to be set */
1004 buf_set_u32(str9xpec_info->options, 63, 1, 1);
1006 /* set option byte address */
1007 str9xpec_set_address(bank, 0x50);
1009 /* execute ISC_PROGRAM command */
1010 str9xpec_set_instr(chain_pos, ISC_PROGRAM, TAP_PI);
1012 field.device = chain_pos;
1013 field.num_bits = 64;
1014 field.out_value = str9xpec_info->options;
1015 field.out_mask = NULL;
1016 field.in_value = NULL;
1017 field.in_check_value = NULL;
1018 field.in_check_mask = NULL;
1019 field.in_handler = NULL;
1020 field.in_handler_priv = NULL;
1022 jtag_add_dr_scan(1, &field, TAP_RTI, NULL);
1024 /* small delay before polling */
1027 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_PI);
1030 field.device = chain_pos;
1032 field.out_value = NULL;
1033 field.out_mask = NULL;
1034 field.in_value = &status;
1035 field.in_check_value = NULL;
1036 field.in_check_mask = NULL;
1037 field.in_handler = NULL;
1038 field.in_handler_priv = NULL;
1040 jtag_add_dr_scan(1, &field, -1, NULL);
1041 jtag_execute_queue();
1043 } while(!(status & ISC_STATUS_BUSY));
1045 str9xpec_isc_disable(bank);
1050 int str9xpec_handle_flash_options_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1057 command_print(cmd_ctx, "str9xpec options_write <bank>");
1061 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1064 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1068 status = str9xpec_write_options(bank);
1070 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1071 return ERROR_FLASH_OPERATION_FAILED;
1076 int str9xpec_handle_flash_options_cmap_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1079 str9xpec_flash_controller_t *str9xpec_info = NULL;
1083 command_print(cmd_ctx, "str9xpec options_cmap <bank> <bank0|bank1>");
1087 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1090 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1094 str9xpec_info = bank->driver_priv;
1096 if (strcmp(args[1], "bank1") == 0)
1098 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 1);
1102 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0);
1108 int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1111 str9xpec_flash_controller_t *str9xpec_info = NULL;
1115 command_print(cmd_ctx, "str9xpec options_lvdthd <bank> <2.4v|2.7v>");
1119 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1122 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1126 str9xpec_info = bank->driver_priv;
1128 if (strcmp(args[1], "2.7v") == 0)
1130 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 1);
1134 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0);
1140 int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1143 str9xpec_flash_controller_t *str9xpec_info = NULL;
1147 command_print(cmd_ctx, "str9xpec options_lvdsel <bank> <vdd|vdd_vddq>");
1151 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1154 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1158 str9xpec_info = bank->driver_priv;
1160 if (strcmp(args[1], "vdd_vddq") == 0)
1162 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 1);
1166 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0);
1172 int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1175 str9xpec_flash_controller_t *str9xpec_info = NULL;
1179 command_print(cmd_ctx, "str9xpec options_lvdwarn <bank> <vdd|vdd_vddq>");
1183 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1186 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1190 str9xpec_info = bank->driver_priv;
1192 if (strcmp(args[1], "vdd_vddq") == 0)
1194 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 1);
1198 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0);
1204 int str9xpec_handle_flash_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1211 command_print(cmd_ctx, "str9xpec lock <bank>");
1215 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1218 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1222 status = str9xpec_lock_device(bank);
1224 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1225 return ERROR_FLASH_OPERATION_FAILED;
1230 int str9xpec_handle_flash_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1237 command_print(cmd_ctx, "str9xpec unlock <bank>");
1241 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1244 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1248 status = str9xpec_unlock_device(bank);
1250 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1251 return ERROR_FLASH_OPERATION_FAILED;
1256 int str9xpec_handle_flash_enable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1260 jtag_device_t* dev0;
1261 jtag_device_t* dev2;
1262 str9xpec_flash_controller_t *str9xpec_info = NULL;
1266 command_print(cmd_ctx, "str9xpec enable_turbo <bank>");
1270 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1273 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1277 str9xpec_info = bank->driver_priv;
1279 chain_pos = str9xpec_info->chain_pos;
1281 /* remove arm core from chain - enter turbo mode */
1283 str9xpec_set_instr(chain_pos+2, 0xD, TAP_RTI);
1284 jtag_execute_queue();
1286 /* modify scan chain - str9 core has been removed */
1287 dev0 = jtag_get_device(chain_pos);
1288 str9xpec_info->devarm = jtag_get_device(chain_pos+1);
1289 dev2 = jtag_get_device(chain_pos+2);
1296 int str9xpec_handle_flash_disable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1300 jtag_device_t* dev0;
1301 str9xpec_flash_controller_t *str9xpec_info = NULL;
1305 command_print(cmd_ctx, "str9xpec disable_turbo <bank>");
1309 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1312 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1316 str9xpec_info = bank->driver_priv;
1318 chain_pos = str9xpec_info->chain_pos;
1320 dev0 = jtag_get_device(chain_pos);
1322 /* exit turbo mode via TLR */
1323 str9xpec_set_instr(chain_pos, ISC_NOOP, TAP_TLR);
1324 jtag_execute_queue();
1326 /* restore previous scan chain */
1327 if( str9xpec_info->devarm ) {
1328 dev0->next = str9xpec_info->devarm;