Constify struct flash_driver instances
[openocd.git] / src / flash / nor / str9xpec.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
20 ***************************************************************************/
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include "imp.h"
27 #include <target/arm7_9_common.h>
28
29 /* ISC commands */
30
31 #define ISC_IDCODE 0xFE
32 #define ISC_MFG_READ 0x4C
33 #define ISC_CONFIGURATION 0x07
34 #define ISC_ENABLE 0x0C
35 #define ISC_DISABLE 0x0F
36 #define ISC_NOOP 0x10
37 #define ISC_ADDRESS_SHIFT 0x11
38 #define ISC_CLR_STATUS 0x13
39 #define ISC_PROGRAM 0x20
40 #define ISC_PROGRAM_SECURITY 0x22
41 #define ISC_PROGRAM_UC 0x23
42 #define ISC_ERASE 0x30
43 #define ISC_READ 0x50
44 #define ISC_BLANK_CHECK 0x60
45
46 /* ISC_DEFAULT bit definitions */
47
48 #define ISC_STATUS_SECURITY 0x40
49 #define ISC_STATUS_INT_ERROR 0x30
50 #define ISC_STATUS_MODE 0x08
51 #define ISC_STATUS_BUSY 0x04
52 #define ISC_STATUS_ERROR 0x03
53
54 /* Option bytes definitions */
55
56 #define STR9XPEC_OPT_CSMAPBIT 48
57 #define STR9XPEC_OPT_LVDTHRESBIT 49
58 #define STR9XPEC_OPT_LVDSELBIT 50
59 #define STR9XPEC_OPT_LVDWARNBIT 51
60 #define STR9XPEC_OPT_OTPBIT 63
61
62 enum str9xpec_status_codes {
63 STR9XPEC_INVALID_COMMAND = 1,
64 STR9XPEC_ISC_SUCCESS = 2,
65 STR9XPEC_ISC_DISABLED = 3,
66 STR9XPEC_ISC_INTFAIL = 32,
67 };
68
69 struct str9xpec_flash_controller {
70 struct jtag_tap *tap;
71 uint32_t *sector_bits;
72 int chain_pos;
73 int isc_enable;
74 uint8_t options[8];
75 };
76
77 static int str9xpec_erase_area(struct flash_bank *bank, int first, int last);
78 static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector);
79 static int str9xpec_write_options(struct flash_bank *bank);
80
81 static int str9xpec_set_instr(struct jtag_tap *tap, uint32_t new_instr, tap_state_t end_state)
82 {
83 if (tap == NULL)
84 return ERROR_TARGET_INVALID;
85
86 if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) {
87 struct scan_field field;
88
89 field.num_bits = tap->ir_length;
90 void *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);
91 field.out_value = t;
92 buf_set_u32(t, 0, field.num_bits, new_instr);
93 field.in_value = NULL;
94
95 jtag_add_ir_scan(tap, &field, end_state);
96
97 free(t);
98 }
99
100 return ERROR_OK;
101 }
102
103 static uint8_t str9xpec_isc_status(struct jtag_tap *tap)
104 {
105 struct scan_field field;
106 uint8_t status;
107
108 if (str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE) != ERROR_OK)
109 return ISC_STATUS_ERROR;
110
111 field.num_bits = 8;
112 field.out_value = NULL;
113 field.in_value = &status;
114
115
116 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
117 jtag_execute_queue();
118
119 LOG_DEBUG("status: 0x%2.2x", status);
120
121 if (status & ISC_STATUS_SECURITY)
122 LOG_INFO("Device Security Bit Set");
123
124 return status;
125 }
126
127 static int str9xpec_isc_enable(struct flash_bank *bank)
128 {
129 uint8_t status;
130 struct jtag_tap *tap;
131 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
132
133 tap = str9xpec_info->tap;
134
135 if (str9xpec_info->isc_enable)
136 return ERROR_OK;
137
138 /* enter isc mode */
139 if (str9xpec_set_instr(tap, ISC_ENABLE, TAP_IDLE) != ERROR_OK)
140 return ERROR_TARGET_INVALID;
141
142 /* check ISC status */
143 status = str9xpec_isc_status(tap);
144 if (status & ISC_STATUS_MODE) {
145 /* we have entered isc mode */
146 str9xpec_info->isc_enable = 1;
147 LOG_DEBUG("ISC_MODE Enabled");
148 }
149
150 return ERROR_OK;
151 }
152
153 static int str9xpec_isc_disable(struct flash_bank *bank)
154 {
155 uint8_t status;
156 struct jtag_tap *tap;
157 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
158
159 tap = str9xpec_info->tap;
160
161 if (!str9xpec_info->isc_enable)
162 return ERROR_OK;
163
164 if (str9xpec_set_instr(tap, ISC_DISABLE, TAP_IDLE) != ERROR_OK)
165 return ERROR_TARGET_INVALID;
166
167 /* delay to handle aborts */
168 jtag_add_sleep(50);
169
170 /* check ISC status */
171 status = str9xpec_isc_status(tap);
172 if (!(status & ISC_STATUS_MODE)) {
173 /* we have left isc mode */
174 str9xpec_info->isc_enable = 0;
175 LOG_DEBUG("ISC_MODE Disabled");
176 }
177
178 return ERROR_OK;
179 }
180
181 static int str9xpec_read_config(struct flash_bank *bank)
182 {
183 struct scan_field field;
184 uint8_t status;
185 struct jtag_tap *tap;
186
187 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
188
189 tap = str9xpec_info->tap;
190
191 LOG_DEBUG("ISC_CONFIGURATION");
192
193 /* execute ISC_CONFIGURATION command */
194 str9xpec_set_instr(tap, ISC_CONFIGURATION, TAP_IRPAUSE);
195
196 field.num_bits = 64;
197 field.out_value = NULL;
198 field.in_value = str9xpec_info->options;
199
200 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
201 jtag_execute_queue();
202
203 status = str9xpec_isc_status(tap);
204
205 return status;
206 }
207
208 static int str9xpec_build_block_list(struct flash_bank *bank)
209 {
210 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
211
212 int i;
213 int num_sectors;
214 int b0_sectors = 0, b1_sectors = 0;
215 uint32_t offset = 0;
216 int b1_size = 0x2000;
217
218 switch (bank->size) {
219 case (256 * 1024):
220 b0_sectors = 4;
221 break;
222 case (512 * 1024):
223 b0_sectors = 8;
224 break;
225 case (1024 * 1024):
226 b0_sectors = 16;
227 break;
228 case (2048 * 1024):
229 b0_sectors = 32;
230 break;
231 case (128 * 1024):
232 b1_size = 0x4000;
233 b1_sectors = 8;
234 break;
235 case (32 * 1024):
236 b1_sectors = 4;
237 break;
238 default:
239 LOG_ERROR("BUG: unknown bank->size encountered");
240 exit(-1);
241 }
242
243 num_sectors = b0_sectors + b1_sectors;
244
245 bank->num_sectors = num_sectors;
246 bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);
247 str9xpec_info->sector_bits = malloc(sizeof(uint32_t) * num_sectors);
248
249 num_sectors = 0;
250
251 for (i = 0; i < b0_sectors; i++) {
252 bank->sectors[num_sectors].offset = offset;
253 bank->sectors[num_sectors].size = 0x10000;
254 offset += bank->sectors[i].size;
255 bank->sectors[num_sectors].is_erased = -1;
256 bank->sectors[num_sectors].is_protected = 1;
257 str9xpec_info->sector_bits[num_sectors++] = i;
258 }
259
260 for (i = 0; i < b1_sectors; i++) {
261 bank->sectors[num_sectors].offset = offset;
262 bank->sectors[num_sectors].size = b1_size;
263 offset += bank->sectors[i].size;
264 bank->sectors[num_sectors].is_erased = -1;
265 bank->sectors[num_sectors].is_protected = 1;
266 str9xpec_info->sector_bits[num_sectors++] = i + 32;
267 }
268
269 return ERROR_OK;
270 }
271
272 /* flash bank str9x <base> <size> 0 0 <target#>
273 */
274 FLASH_BANK_COMMAND_HANDLER(str9xpec_flash_bank_command)
275 {
276 struct str9xpec_flash_controller *str9xpec_info;
277 struct arm *arm = NULL;
278 struct arm7_9_common *arm7_9 = NULL;
279 struct arm_jtag *jtag_info = NULL;
280
281 if (CMD_ARGC < 6)
282 return ERROR_COMMAND_SYNTAX_ERROR;
283
284 str9xpec_info = malloc(sizeof(struct str9xpec_flash_controller));
285 bank->driver_priv = str9xpec_info;
286
287 /* REVISIT verify that the jtag position of flash controller is
288 * right after *THIS* core, which must be a STR9xx core ...
289 */
290 arm = bank->target->arch_info;
291 arm7_9 = arm->arch_info;
292 jtag_info = &arm7_9->jtag_info;
293
294 /* The core is the next tap after the flash controller in the chain */
295 str9xpec_info->tap = jtag_tap_by_position(jtag_info->tap->abs_chain_position - 1);
296 str9xpec_info->isc_enable = 0;
297
298 str9xpec_build_block_list(bank);
299
300 /* clear option byte register */
301 buf_set_u32(str9xpec_info->options, 0, 64, 0);
302
303 return ERROR_OK;
304 }
305
306 static int str9xpec_blank_check(struct flash_bank *bank, int first, int last)
307 {
308 struct scan_field field;
309 uint8_t status;
310 struct jtag_tap *tap;
311 int i;
312 uint8_t *buffer = NULL;
313
314 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
315
316 tap = str9xpec_info->tap;
317
318 if (!str9xpec_info->isc_enable)
319 str9xpec_isc_enable(bank);
320
321 if (!str9xpec_info->isc_enable)
322 return ERROR_FLASH_OPERATION_FAILED;
323
324 buffer = calloc(DIV_ROUND_UP(64, 8), 1);
325
326 LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first, last);
327
328 for (i = first; i <= last; i++)
329 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
330
331 /* execute ISC_BLANK_CHECK command */
332 str9xpec_set_instr(tap, ISC_BLANK_CHECK, TAP_IRPAUSE);
333
334 field.num_bits = 64;
335 field.out_value = buffer;
336 field.in_value = NULL;
337
338 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
339 jtag_add_sleep(40000);
340
341 /* read blank check result */
342 field.num_bits = 64;
343 field.out_value = NULL;
344 field.in_value = buffer;
345
346 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
347 jtag_execute_queue();
348
349 status = str9xpec_isc_status(tap);
350
351 for (i = first; i <= last; i++) {
352 if (buf_get_u32(buffer, str9xpec_info->sector_bits[i], 1))
353 bank->sectors[i].is_erased = 0;
354 else
355 bank->sectors[i].is_erased = 1;
356 }
357
358 free(buffer);
359
360 str9xpec_isc_disable(bank);
361
362 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
363 return ERROR_FLASH_OPERATION_FAILED;
364 return ERROR_OK;
365 }
366
367 static int str9xpec_protect_check(struct flash_bank *bank)
368 {
369 uint8_t status;
370 int i;
371
372 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
373
374 status = str9xpec_read_config(bank);
375
376 for (i = 0; i < bank->num_sectors; i++) {
377 if (buf_get_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1))
378 bank->sectors[i].is_protected = 1;
379 else
380 bank->sectors[i].is_protected = 0;
381 }
382
383 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
384 return ERROR_FLASH_OPERATION_FAILED;
385 return ERROR_OK;
386 }
387
388 static int str9xpec_erase_area(struct flash_bank *bank, int first, int last)
389 {
390 struct scan_field field;
391 uint8_t status;
392 struct jtag_tap *tap;
393 int i;
394 uint8_t *buffer = NULL;
395
396 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
397
398 tap = str9xpec_info->tap;
399
400 if (!str9xpec_info->isc_enable)
401 str9xpec_isc_enable(bank);
402
403 if (!str9xpec_info->isc_enable)
404 return ISC_STATUS_ERROR;
405
406 buffer = calloc(DIV_ROUND_UP(64, 8), 1);
407
408 LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first, last);
409
410 /* last bank: 0xFF signals a full erase (unlock complete device) */
411 /* last bank: 0xFE signals a option byte erase */
412 if (last == 0xFF) {
413 for (i = 0; i < 64; i++)
414 buf_set_u32(buffer, i, 1, 1);
415 } else if (last == 0xFE)
416 buf_set_u32(buffer, 49, 1, 1);
417 else {
418 for (i = first; i <= last; i++)
419 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
420 }
421
422 LOG_DEBUG("ISC_ERASE");
423
424 /* execute ISC_ERASE command */
425 str9xpec_set_instr(tap, ISC_ERASE, TAP_IRPAUSE);
426
427 field.num_bits = 64;
428 field.out_value = buffer;
429 field.in_value = NULL;
430
431 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
432 jtag_execute_queue();
433
434 jtag_add_sleep(10);
435
436 /* wait for erase completion */
437 while (!((status = str9xpec_isc_status(tap)) & ISC_STATUS_BUSY))
438 alive_sleep(1);
439
440 free(buffer);
441
442 str9xpec_isc_disable(bank);
443
444 return status;
445 }
446
447 static int str9xpec_erase(struct flash_bank *bank, int first, int last)
448 {
449 int status;
450
451 status = str9xpec_erase_area(bank, first, last);
452
453 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
454 return ERROR_FLASH_OPERATION_FAILED;
455
456 return ERROR_OK;
457 }
458
459 static int str9xpec_lock_device(struct flash_bank *bank)
460 {
461 struct scan_field field;
462 uint8_t status;
463 struct jtag_tap *tap;
464 struct str9xpec_flash_controller *str9xpec_info = NULL;
465
466 str9xpec_info = bank->driver_priv;
467 tap = str9xpec_info->tap;
468
469 if (!str9xpec_info->isc_enable)
470 str9xpec_isc_enable(bank);
471
472 if (!str9xpec_info->isc_enable)
473 return ISC_STATUS_ERROR;
474
475 /* set security address */
476 str9xpec_set_address(bank, 0x80);
477
478 /* execute ISC_PROGRAM command */
479 str9xpec_set_instr(tap, ISC_PROGRAM_SECURITY, TAP_IDLE);
480
481 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
482
483 do {
484 field.num_bits = 8;
485 field.out_value = NULL;
486 field.in_value = &status;
487
488 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
489 jtag_execute_queue();
490
491 } while (!(status & ISC_STATUS_BUSY));
492
493 str9xpec_isc_disable(bank);
494
495 return status;
496 }
497
498 static int str9xpec_unlock_device(struct flash_bank *bank)
499 {
500 uint8_t status;
501
502 status = str9xpec_erase_area(bank, 0, 255);
503
504 return status;
505 }
506
507 static int str9xpec_protect(struct flash_bank *bank, int set, int first, int last)
508 {
509 uint8_t status;
510 int i;
511
512 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
513
514 status = str9xpec_read_config(bank);
515
516 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
517 return ERROR_FLASH_OPERATION_FAILED;
518
519 LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first, last);
520
521 /* last bank: 0xFF signals a full device protect */
522 if (last == 0xFF) {
523 if (set)
524 status = str9xpec_lock_device(bank);
525 else {
526 /* perform full erase to unlock device */
527 status = str9xpec_unlock_device(bank);
528 }
529 } else {
530 for (i = first; i <= last; i++) {
531 if (set)
532 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 1);
533 else
534 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 0);
535 }
536
537 status = str9xpec_write_options(bank);
538 }
539
540 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
541 return ERROR_FLASH_OPERATION_FAILED;
542
543 return ERROR_OK;
544 }
545
546 static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector)
547 {
548 struct jtag_tap *tap;
549 struct scan_field field;
550 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
551
552 tap = str9xpec_info->tap;
553
554 /* set flash controller address */
555 str9xpec_set_instr(tap, ISC_ADDRESS_SHIFT, TAP_IRPAUSE);
556
557 field.num_bits = 8;
558 field.out_value = &sector;
559 field.in_value = NULL;
560
561 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
562
563 return ERROR_OK;
564 }
565
566 static int str9xpec_write(struct flash_bank *bank, const uint8_t *buffer,
567 uint32_t offset, uint32_t count)
568 {
569 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
570 uint32_t dwords_remaining = (count / 8);
571 uint32_t bytes_remaining = (count & 0x00000007);
572 uint32_t bytes_written = 0;
573 uint8_t status;
574 uint32_t check_address = offset;
575 struct jtag_tap *tap;
576 struct scan_field field;
577 uint8_t *scanbuf;
578 int i;
579 int first_sector = 0;
580 int last_sector = 0;
581
582 tap = str9xpec_info->tap;
583
584 if (!str9xpec_info->isc_enable)
585 str9xpec_isc_enable(bank);
586
587 if (!str9xpec_info->isc_enable)
588 return ERROR_FLASH_OPERATION_FAILED;
589
590 if (offset & 0x7) {
591 LOG_WARNING("offset 0x%" PRIx32 " breaks required 8-byte alignment", offset);
592 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
593 }
594
595 for (i = 0; i < bank->num_sectors; i++) {
596 uint32_t sec_start = bank->sectors[i].offset;
597 uint32_t sec_end = sec_start + bank->sectors[i].size;
598
599 /* check if destination falls within the current sector */
600 if ((check_address >= sec_start) && (check_address < sec_end)) {
601 /* check if destination ends in the current sector */
602 if (offset + count < sec_end)
603 check_address = offset + count;
604 else
605 check_address = sec_end;
606 }
607
608 if ((offset >= sec_start) && (offset < sec_end))
609 first_sector = i;
610
611 if ((offset + count >= sec_start) && (offset + count < sec_end))
612 last_sector = i;
613 }
614
615 if (check_address != offset + count)
616 return ERROR_FLASH_DST_OUT_OF_BANK;
617
618 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
619
620 scanbuf = calloc(DIV_ROUND_UP(64, 8), 1);
621
622 LOG_DEBUG("ISC_PROGRAM");
623
624 for (i = first_sector; i <= last_sector; i++) {
625 str9xpec_set_address(bank, str9xpec_info->sector_bits[i]);
626
627 dwords_remaining = dwords_remaining < (bank->sectors[i].size/8)
628 ? dwords_remaining : (bank->sectors[i].size/8);
629
630 while (dwords_remaining > 0) {
631 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
632
633 field.num_bits = 64;
634 field.out_value = (buffer + bytes_written);
635 field.in_value = NULL;
636
637 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
638
639 /* small delay before polling */
640 jtag_add_sleep(50);
641
642 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
643
644 do {
645 field.num_bits = 8;
646 field.out_value = NULL;
647 field.in_value = scanbuf;
648
649 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
650 jtag_execute_queue();
651
652 status = buf_get_u32(scanbuf, 0, 8);
653
654 } while (!(status & ISC_STATUS_BUSY));
655
656 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
657 return ERROR_FLASH_OPERATION_FAILED;
658
659 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
660 return ERROR_FLASH_OPERATION_FAILED; */
661
662 dwords_remaining--;
663 bytes_written += 8;
664 }
665 }
666
667 if (bytes_remaining) {
668 uint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
669
670 /* copy the last remaining bytes into the write buffer */
671 memcpy(last_dword, buffer+bytes_written, bytes_remaining);
672
673 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
674
675 field.num_bits = 64;
676 field.out_value = last_dword;
677 field.in_value = NULL;
678
679 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
680
681 /* small delay before polling */
682 jtag_add_sleep(50);
683
684 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
685
686 do {
687 field.num_bits = 8;
688 field.out_value = NULL;
689 field.in_value = scanbuf;
690
691 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
692 jtag_execute_queue();
693
694 status = buf_get_u32(scanbuf, 0, 8);
695
696 } while (!(status & ISC_STATUS_BUSY));
697
698 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
699 return ERROR_FLASH_OPERATION_FAILED;
700
701 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
702 return ERROR_FLASH_OPERATION_FAILED; */
703 }
704
705 free(scanbuf);
706
707 str9xpec_isc_disable(bank);
708
709 return ERROR_OK;
710 }
711
712 static int str9xpec_probe(struct flash_bank *bank)
713 {
714 return ERROR_OK;
715 }
716
717 COMMAND_HANDLER(str9xpec_handle_part_id_command)
718 {
719 struct scan_field field;
720 uint8_t *buffer = NULL;
721 struct jtag_tap *tap;
722 uint32_t idcode;
723 struct str9xpec_flash_controller *str9xpec_info = NULL;
724
725 if (CMD_ARGC < 1)
726 return ERROR_COMMAND_SYNTAX_ERROR;
727
728 struct flash_bank *bank;
729 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
730 if (ERROR_OK != retval)
731 return retval;
732
733 str9xpec_info = bank->driver_priv;
734 tap = str9xpec_info->tap;
735
736 buffer = calloc(DIV_ROUND_UP(32, 8), 1);
737
738 str9xpec_set_instr(tap, ISC_IDCODE, TAP_IRPAUSE);
739
740 field.num_bits = 32;
741 field.out_value = NULL;
742 field.in_value = buffer;
743
744 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
745 jtag_execute_queue();
746
747 idcode = buf_get_u32(buffer, 0, 32);
748
749 command_print(CMD_CTX, "str9xpec part id: 0x%8.8" PRIx32 "", idcode);
750
751 free(buffer);
752
753 return ERROR_OK;
754 }
755
756 static int str9xpec_erase_check(struct flash_bank *bank)
757 {
758 return str9xpec_blank_check(bank, 0, bank->num_sectors - 1);
759 }
760
761 COMMAND_HANDLER(str9xpec_handle_flash_options_read_command)
762 {
763 uint8_t status;
764 struct str9xpec_flash_controller *str9xpec_info = NULL;
765
766 if (CMD_ARGC < 1)
767 return ERROR_COMMAND_SYNTAX_ERROR;
768
769 struct flash_bank *bank;
770 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
771 if (ERROR_OK != retval)
772 return retval;
773
774 str9xpec_info = bank->driver_priv;
775
776 status = str9xpec_read_config(bank);
777
778 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
779 return ERROR_FLASH_OPERATION_FAILED;
780
781 /* boot bank */
782 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1))
783 command_print(CMD_CTX, "CS Map: bank1");
784 else
785 command_print(CMD_CTX, "CS Map: bank0");
786
787 /* OTP lock */
788 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1))
789 command_print(CMD_CTX, "OTP Lock: OTP Locked");
790 else
791 command_print(CMD_CTX, "OTP Lock: OTP Unlocked");
792
793 /* LVD Threshold */
794 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1))
795 command_print(CMD_CTX, "LVD Threshold: 2.7v");
796 else
797 command_print(CMD_CTX, "LVD Threshold: 2.4v");
798
799 /* LVD reset warning */
800 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1))
801 command_print(CMD_CTX, "LVD Reset Warning: VDD or VDDQ Inputs");
802 else
803 command_print(CMD_CTX, "LVD Reset Warning: VDD Input Only");
804
805 /* LVD reset select */
806 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1))
807 command_print(CMD_CTX, "LVD Reset Selection: VDD or VDDQ Inputs");
808 else
809 command_print(CMD_CTX, "LVD Reset Selection: VDD Input Only");
810
811 return ERROR_OK;
812 }
813
814 static int str9xpec_write_options(struct flash_bank *bank)
815 {
816 struct scan_field field;
817 uint8_t status;
818 struct jtag_tap *tap;
819 struct str9xpec_flash_controller *str9xpec_info = NULL;
820
821 str9xpec_info = bank->driver_priv;
822 tap = str9xpec_info->tap;
823
824 /* erase config options first */
825 status = str9xpec_erase_area(bank, 0xFE, 0xFE);
826
827 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
828 return status;
829
830 if (!str9xpec_info->isc_enable)
831 str9xpec_isc_enable(bank);
832
833 if (!str9xpec_info->isc_enable)
834 return ISC_STATUS_ERROR;
835
836 /* according to data 64th bit has to be set */
837 buf_set_u32(str9xpec_info->options, 63, 1, 1);
838
839 /* set option byte address */
840 str9xpec_set_address(bank, 0x50);
841
842 /* execute ISC_PROGRAM command */
843 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
844
845 field.num_bits = 64;
846 field.out_value = str9xpec_info->options;
847 field.in_value = NULL;
848
849 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
850
851 /* small delay before polling */
852 jtag_add_sleep(50);
853
854 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
855
856 do {
857 field.num_bits = 8;
858 field.out_value = NULL;
859 field.in_value = &status;
860
861 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
862 jtag_execute_queue();
863
864 } while (!(status & ISC_STATUS_BUSY));
865
866 str9xpec_isc_disable(bank);
867
868 return status;
869 }
870
871 COMMAND_HANDLER(str9xpec_handle_flash_options_write_command)
872 {
873 uint8_t status;
874
875 if (CMD_ARGC < 1)
876 return ERROR_COMMAND_SYNTAX_ERROR;
877
878 struct flash_bank *bank;
879 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
880 if (ERROR_OK != retval)
881 return retval;
882
883 status = str9xpec_write_options(bank);
884
885 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
886 return ERROR_FLASH_OPERATION_FAILED;
887
888 command_print(CMD_CTX, "str9xpec write options complete.\n"
889 "INFO: a reset or power cycle is required "
890 "for the new settings to take effect.");
891
892 return ERROR_OK;
893 }
894
895 COMMAND_HANDLER(str9xpec_handle_flash_options_cmap_command)
896 {
897 struct str9xpec_flash_controller *str9xpec_info = NULL;
898
899 if (CMD_ARGC < 2)
900 return ERROR_COMMAND_SYNTAX_ERROR;
901
902 struct flash_bank *bank;
903 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
904 if (ERROR_OK != retval)
905 return retval;
906
907 str9xpec_info = bank->driver_priv;
908
909 if (strcmp(CMD_ARGV[1], "bank1") == 0)
910 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 1);
911 else
912 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0);
913
914 return ERROR_OK;
915 }
916
917 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdthd_command)
918 {
919 struct str9xpec_flash_controller *str9xpec_info = NULL;
920
921 if (CMD_ARGC < 2)
922 return ERROR_COMMAND_SYNTAX_ERROR;
923
924 struct flash_bank *bank;
925 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
926 if (ERROR_OK != retval)
927 return retval;
928
929 str9xpec_info = bank->driver_priv;
930
931 if (strcmp(CMD_ARGV[1], "2.7v") == 0)
932 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 1);
933 else
934 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0);
935
936 return ERROR_OK;
937 }
938
939 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdsel_command)
940 {
941 struct str9xpec_flash_controller *str9xpec_info = NULL;
942
943 if (CMD_ARGC < 2)
944 return ERROR_COMMAND_SYNTAX_ERROR;
945
946 struct flash_bank *bank;
947 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
948 if (ERROR_OK != retval)
949 return retval;
950
951 str9xpec_info = bank->driver_priv;
952
953 if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0)
954 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 1);
955 else
956 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0);
957
958 return ERROR_OK;
959 }
960
961 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdwarn_command)
962 {
963 struct str9xpec_flash_controller *str9xpec_info = NULL;
964
965 if (CMD_ARGC < 2)
966 return ERROR_COMMAND_SYNTAX_ERROR;
967
968 struct flash_bank *bank;
969 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
970 if (ERROR_OK != retval)
971 return retval;
972
973 str9xpec_info = bank->driver_priv;
974
975 if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0)
976 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 1);
977 else
978 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0);
979
980 return ERROR_OK;
981 }
982
983 COMMAND_HANDLER(str9xpec_handle_flash_lock_command)
984 {
985 uint8_t status;
986
987 if (CMD_ARGC < 1)
988 return ERROR_COMMAND_SYNTAX_ERROR;
989
990 struct flash_bank *bank;
991 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
992 if (ERROR_OK != retval)
993 return retval;
994
995 status = str9xpec_lock_device(bank);
996
997 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
998 return ERROR_FLASH_OPERATION_FAILED;
999
1000 return ERROR_OK;
1001 }
1002
1003 COMMAND_HANDLER(str9xpec_handle_flash_unlock_command)
1004 {
1005 uint8_t status;
1006
1007 if (CMD_ARGC < 1)
1008 return ERROR_COMMAND_SYNTAX_ERROR;
1009
1010 struct flash_bank *bank;
1011 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1012 if (ERROR_OK != retval)
1013 return retval;
1014
1015 status = str9xpec_unlock_device(bank);
1016
1017 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1018 return ERROR_FLASH_OPERATION_FAILED;
1019
1020 command_print(CMD_CTX, "str9xpec unlocked.\n"
1021 "INFO: a reset or power cycle is required "
1022 "for the new settings to take effect.");
1023
1024 return ERROR_OK;
1025 }
1026
1027 COMMAND_HANDLER(str9xpec_handle_flash_enable_turbo_command)
1028 {
1029 struct jtag_tap *tap0;
1030 struct jtag_tap *tap1;
1031 struct jtag_tap *tap2;
1032 struct str9xpec_flash_controller *str9xpec_info = NULL;
1033
1034 if (CMD_ARGC < 1)
1035 return ERROR_COMMAND_SYNTAX_ERROR;
1036
1037 struct flash_bank *bank;
1038 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1039 if (ERROR_OK != retval)
1040 return retval;
1041
1042 str9xpec_info = bank->driver_priv;
1043
1044 /* remove arm core from chain - enter turbo mode */
1045 tap0 = str9xpec_info->tap;
1046 if (tap0 == NULL) {
1047 /* things are *WRONG* */
1048 command_print(CMD_CTX, "**STR9FLASH** (tap0) invalid chain?");
1049 return ERROR_FAIL;
1050 }
1051 tap1 = tap0->next_tap;
1052 if (tap1 == NULL) {
1053 /* things are *WRONG* */
1054 command_print(CMD_CTX, "**STR9FLASH** (tap1) invalid chain?");
1055 return ERROR_FAIL;
1056 }
1057 tap2 = tap1->next_tap;
1058 if (tap2 == NULL) {
1059 /* things are *WRONG* */
1060 command_print(CMD_CTX, "**STR9FLASH** (tap2) invalid chain?");
1061 return ERROR_FAIL;
1062 }
1063
1064 /* enable turbo mode - TURBO-PROG-ENABLE */
1065 str9xpec_set_instr(tap2, 0xD, TAP_IDLE);
1066 retval = jtag_execute_queue();
1067 if (retval != ERROR_OK)
1068 return retval;
1069
1070 /* modify scan chain - str9 core has been removed */
1071 tap1->enabled = 0;
1072
1073 return ERROR_OK;
1074 }
1075
1076 COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command)
1077 {
1078 struct jtag_tap *tap;
1079 struct str9xpec_flash_controller *str9xpec_info = NULL;
1080
1081 if (CMD_ARGC < 1)
1082 return ERROR_COMMAND_SYNTAX_ERROR;
1083
1084 struct flash_bank *bank;
1085 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1086 if (ERROR_OK != retval)
1087 return retval;
1088
1089 str9xpec_info = bank->driver_priv;
1090 tap = str9xpec_info->tap;
1091
1092 if (tap == NULL)
1093 return ERROR_FAIL;
1094
1095 /* exit turbo mode via RESET */
1096 str9xpec_set_instr(tap, ISC_NOOP, TAP_IDLE);
1097 jtag_add_tlr();
1098 jtag_execute_queue();
1099
1100 /* restore previous scan chain */
1101 if (tap->next_tap)
1102 tap->next_tap->enabled = 1;
1103
1104 return ERROR_OK;
1105 }
1106
1107 static const struct command_registration str9xpec_config_command_handlers[] = {
1108 {
1109 .name = "enable_turbo",
1110 .usage = "<bank>",
1111 .handler = str9xpec_handle_flash_enable_turbo_command,
1112 .mode = COMMAND_EXEC,
1113 .help = "enable str9xpec turbo mode",
1114 },
1115 {
1116 .name = "disable_turbo",
1117 .usage = "<bank>",
1118 .handler = str9xpec_handle_flash_disable_turbo_command,
1119 .mode = COMMAND_EXEC,
1120 .help = "disable str9xpec turbo mode",
1121 },
1122 {
1123 .name = "options_cmap",
1124 .usage = "<bank> <bank0 | bank1>",
1125 .handler = str9xpec_handle_flash_options_cmap_command,
1126 .mode = COMMAND_EXEC,
1127 .help = "configure str9xpec boot sector",
1128 },
1129 {
1130 .name = "options_lvdthd",
1131 .usage = "<bank> <2.4v | 2.7v>",
1132 .handler = str9xpec_handle_flash_options_lvdthd_command,
1133 .mode = COMMAND_EXEC,
1134 .help = "configure str9xpec lvd threshold",
1135 },
1136 {
1137 .name = "options_lvdsel",
1138 .usage = "<bank> <vdd | vdd_vddq>",
1139 .handler = str9xpec_handle_flash_options_lvdsel_command,
1140 .mode = COMMAND_EXEC,
1141 .help = "configure str9xpec lvd selection",
1142 },
1143 {
1144 .name = "options_lvdwarn",
1145 .usage = "<bank> <vdd | vdd_vddq>",
1146 .handler = str9xpec_handle_flash_options_lvdwarn_command,
1147 .mode = COMMAND_EXEC,
1148 .help = "configure str9xpec lvd warning",
1149 },
1150 {
1151 .name = "options_read",
1152 .usage = "<bank>",
1153 .handler = str9xpec_handle_flash_options_read_command,
1154 .mode = COMMAND_EXEC,
1155 .help = "read str9xpec options",
1156 },
1157 {
1158 .name = "options_write",
1159 .usage = "<bank>",
1160 .handler = str9xpec_handle_flash_options_write_command,
1161 .mode = COMMAND_EXEC,
1162 .help = "write str9xpec options",
1163 },
1164 {
1165 .name = "lock",
1166 .usage = "<bank>",
1167 .handler = str9xpec_handle_flash_lock_command,
1168 .mode = COMMAND_EXEC,
1169 .help = "lock str9xpec device",
1170 },
1171 {
1172 .name = "unlock",
1173 .usage = "<bank>",
1174 .handler = str9xpec_handle_flash_unlock_command,
1175 .mode = COMMAND_EXEC,
1176 .help = "unlock str9xpec device",
1177 },
1178 {
1179 .name = "part_id",
1180 .handler = str9xpec_handle_part_id_command,
1181 .mode = COMMAND_EXEC,
1182 .help = "print part id of str9xpec flash bank <num>",
1183 },
1184 COMMAND_REGISTRATION_DONE
1185 };
1186
1187 static const struct command_registration str9xpec_command_handlers[] = {
1188 {
1189 .name = "str9xpec",
1190 .mode = COMMAND_ANY,
1191 .help = "str9xpec flash command group",
1192 .usage = "",
1193 .chain = str9xpec_config_command_handlers,
1194 },
1195 COMMAND_REGISTRATION_DONE
1196 };
1197
1198 const struct flash_driver str9xpec_flash = {
1199 .name = "str9xpec",
1200 .commands = str9xpec_command_handlers,
1201 .flash_bank_command = str9xpec_flash_bank_command,
1202 .erase = str9xpec_erase,
1203 .protect = str9xpec_protect,
1204 .write = str9xpec_write,
1205 .read = default_flash_read,
1206 .probe = str9xpec_probe,
1207 .auto_probe = str9xpec_probe,
1208 .erase_check = str9xpec_erase_check,
1209 .protect_check = str9xpec_protect_check,
1210 .free_driver_priv = default_flash_free_driver_priv,
1211 };