coding style: remove useless break after a goto or return
[openocd.git] / src / flash / nor / xcf.c
blobba35c2c10c5203c3ce57e168764b1a33b13fb958
1 /***************************************************************************
2 * Copyright (C) 2016 by Uladzimir Pylinski aka barthess *
3 * barthess@yandex.ru *
4 * *
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. *
9 * *
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. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
17 ***************************************************************************/
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
23 #include <string.h>
25 #include "imp.h"
26 #include <jtag/jtag.h>
27 #include <helper/time_support.h>
30 ******************************************************************************
31 * DEFINES
32 ******************************************************************************
35 #define SECTOR_ERASE_TIMEOUT_MS (35 * 1000)
37 #define XCF_PAGE_SIZE 32
38 #define XCF_DATA_SECTOR_SIZE (1024 * 1024)
40 #define ID_XCF01S 0x05044093
41 #define ID_XCF02S 0x05045093
42 #define ID_XCF04S 0x05046093
43 #define ID_XCF08P 0x05057093
44 #define ID_XCF16P 0x05058093
45 #define ID_XCF32P 0x05059093
46 #define ID_MEANINGFUL_MASK 0x0FFFFFFF
48 const char *xcf_name_list[] = {
49 "XCF08P",
50 "XCF16P",
51 "XCF32P",
52 "unknown"
55 struct xcf_priv {
56 bool probed;
59 struct xcf_status {
60 bool isc_error; /* false == OK, true == error */
61 bool prog_error; /* false == OK, true == error */
62 bool prog_busy; /* false == idle, true == busy */
63 bool isc_mode; /* false == normal mode, true == ISC mode */
67 ******************************************************************************
68 * GLOBAL VARIABLES
69 ******************************************************************************
71 static const uint8_t CMD_BYPASS[2] = {0xFF, 0xFF};
73 static const uint8_t CMD_ISC_ADDRESS_SHIFT[2] = {0xEB, 0x00};
74 static const uint8_t CMD_ISC_DATA_SHIFT[2] = {0xED, 0x00};
75 static const uint8_t CMD_ISC_DISABLE[2] = {0xF0, 0x00};
76 static const uint8_t CMD_ISC_ENABLE[2] = {0xE8, 0x00};
77 static const uint8_t CMD_ISC_ERASE[2] = {0xEC, 0x00};
78 static const uint8_t CMD_ISC_PROGRAM[2] = {0xEA, 0x00};
80 static const uint8_t CMD_XSC_BLANK_CHECK[2] = {0x0D, 0x00};
81 static const uint8_t CMD_XSC_CONFIG[2] = {0xEE, 0x00};
82 static const uint8_t CMD_XSC_DATA_BTC[2] = {0xF2, 0x00};
83 static const uint8_t CMD_XSC_DATA_CCB[2] = {0x0C, 0x00};
84 static const uint8_t CMD_XSC_DATA_DONE[2] = {0x09, 0x00};
85 static const uint8_t CMD_XSC_DATA_SUCR[2] = {0x0E, 0x00};
86 static const uint8_t CMD_XSC_DATA_WRPT[2] = {0xF7, 0x00};
87 static const uint8_t CMD_XSC_OP_STATUS[2] = {0xE3, 0x00};
88 static const uint8_t CMD_XSC_READ[2] = {0xEF, 0x00};
89 static const uint8_t CMD_XSC_UNLOCK[2] = {0x55, 0xAA};
92 ******************************************************************************
93 * LOCAL FUNCTIONS
94 ******************************************************************************
97 static const char *product_name(const struct flash_bank *bank)
100 switch (bank->target->tap->idcode & ID_MEANINGFUL_MASK) {
101 case ID_XCF08P:
102 return xcf_name_list[0];
103 case ID_XCF16P:
104 return xcf_name_list[1];
105 case ID_XCF32P:
106 return xcf_name_list[2];
107 default:
108 return xcf_name_list[3];
112 static void fill_sector_table(struct flash_bank *bank)
114 /* Note: is_erased and is_protected fields must be set here to an unknown
115 * state, they will be correctly filled from other API calls. */
117 int i = 0;
119 for (i = 0; i < bank->num_sectors; i++) {
120 bank->sectors[i].is_erased = -1;
121 bank->sectors[i].is_protected = -1;
123 for (i = 0; i < bank->num_sectors; i++) {
124 bank->sectors[i].size = XCF_DATA_SECTOR_SIZE;
125 bank->sectors[i].offset = i * XCF_DATA_SECTOR_SIZE;
128 bank->size = bank->num_sectors * XCF_DATA_SECTOR_SIZE;
131 static struct xcf_status read_status(struct flash_bank *bank)
133 struct xcf_status ret;
134 uint8_t irdata[2];
135 struct scan_field scan;
137 scan.check_mask = NULL;
138 scan.check_value = NULL;
139 scan.num_bits = 16;
140 scan.out_value = CMD_BYPASS;
141 scan.in_value = irdata;
143 jtag_add_ir_scan(bank->target->tap, &scan, TAP_IDLE);
144 jtag_execute_queue();
146 ret.isc_error = ((irdata[0] >> 7) & 3) == 0b01;
147 ret.prog_error = ((irdata[0] >> 5) & 3) == 0b01;
148 ret.prog_busy = ((irdata[0] >> 4) & 1) == 0;
149 ret.isc_mode = ((irdata[0] >> 3) & 1) == 1;
151 return ret;
154 static int isc_enter(struct flash_bank *bank)
157 struct xcf_status status = read_status(bank);
159 if (true == status.isc_mode)
160 return ERROR_OK;
161 else {
162 struct scan_field scan;
164 scan.check_mask = NULL;
165 scan.check_value = NULL;
166 scan.num_bits = 16;
167 scan.out_value = CMD_ISC_ENABLE;
168 scan.in_value = NULL;
170 jtag_add_ir_scan(bank->target->tap, &scan, TAP_IDLE);
171 jtag_execute_queue();
173 status = read_status(bank);
174 if (false == status.isc_mode) {
175 LOG_ERROR("*** XCF: FAILED to enter ISC mode");
176 return ERROR_FLASH_OPERATION_FAILED;
179 return ERROR_OK;
183 static int isc_leave(struct flash_bank *bank)
186 struct xcf_status status = read_status(bank);
188 if (false == status.isc_mode)
189 return ERROR_OK;
190 else {
191 struct scan_field scan;
193 scan.check_mask = NULL;
194 scan.check_value = NULL;
195 scan.num_bits = 16;
196 scan.out_value = CMD_ISC_DISABLE;
197 scan.in_value = NULL;
199 jtag_add_ir_scan(bank->target->tap, &scan, TAP_IDLE);
200 jtag_execute_queue();
201 alive_sleep(1); /* device needs 50 uS to leave ISC mode */
203 status = read_status(bank);
204 if (true == status.isc_mode) {
205 LOG_ERROR("*** XCF: FAILED to leave ISC mode");
206 return ERROR_FLASH_OPERATION_FAILED;
209 return ERROR_OK;
213 static int sector_state(uint8_t wrpt, int sector)
215 if (((wrpt >> sector) & 1) == 1)
216 return 0;
217 else
218 return 1;
221 static uint8_t fill_select_block(int first, int last)
223 uint8_t ret = 0;
224 for (int i = first; i <= last; i++)
225 ret |= 1 << i;
226 return ret;
229 static int isc_read_register(struct flash_bank *bank, const uint8_t *cmd,
230 uint8_t *data_buf, int num_bits)
232 struct scan_field scan;
234 scan.check_mask = NULL;
235 scan.check_value = NULL;
236 scan.out_value = cmd;
237 scan.in_value = NULL;
238 scan.num_bits = 16;
239 jtag_add_ir_scan(bank->target->tap, &scan, TAP_DRSHIFT);
241 scan.out_value = NULL;
242 scan.in_value = data_buf;
243 scan.num_bits = num_bits;
244 jtag_add_dr_scan(bank->target->tap, 1, &scan, TAP_IDLE);
246 return jtag_execute_queue();
249 static int isc_wait_erase_program(struct flash_bank *bank, int64_t timeout_ms)
252 uint8_t isc_default;
253 int64_t t0 = timeval_ms();
254 int64_t dt;
256 do {
257 isc_read_register(bank, CMD_XSC_OP_STATUS, &isc_default, 8);
258 if (((isc_default >> 2) & 1) == 1)
259 return ERROR_OK;
260 dt = timeval_ms() - t0;
261 } while (dt <= timeout_ms);
262 return ERROR_FLASH_OPERATION_FAILED;
266 * helper function for procedures without program jtag command at the end
268 static int isc_set_register(struct flash_bank *bank, const uint8_t *cmd,
269 const uint8_t *data_buf, int num_bits, int64_t timeout_ms)
271 struct scan_field scan;
273 scan.check_mask = NULL;
274 scan.check_value = NULL;
275 scan.num_bits = 16;
276 scan.out_value = cmd;
277 scan.in_value = NULL;
278 jtag_add_ir_scan(bank->target->tap, &scan, TAP_DRSHIFT);
280 scan.num_bits = num_bits;
281 scan.out_value = data_buf;
282 scan.in_value = NULL;
283 jtag_add_dr_scan(bank->target->tap, 1, &scan, TAP_IDLE);
285 if (0 == timeout_ms)
286 return jtag_execute_queue();
287 else
288 return isc_wait_erase_program(bank, timeout_ms);
292 * helper function for procedures required program jtag command at the end
294 static int isc_program_register(struct flash_bank *bank, const uint8_t *cmd,
295 const uint8_t *data_buf, int num_bits, int64_t timeout_ms)
297 struct scan_field scan;
299 scan.check_mask = NULL;
300 scan.check_value = NULL;
301 scan.num_bits = 16;
302 scan.out_value = cmd;
303 scan.in_value = NULL;
304 jtag_add_ir_scan(bank->target->tap, &scan, TAP_DRSHIFT);
306 scan.num_bits = num_bits;
307 scan.out_value = data_buf;
308 scan.in_value = NULL;
309 jtag_add_dr_scan(bank->target->tap, 1, &scan, TAP_IRSHIFT);
311 scan.num_bits = 16;
312 scan.out_value = CMD_ISC_PROGRAM;
313 scan.in_value = NULL;
314 jtag_add_ir_scan(bank->target->tap, &scan, TAP_IDLE);
316 if (0 == timeout_ms)
317 return jtag_execute_queue();
318 else
319 return isc_wait_erase_program(bank, timeout_ms);
322 static int isc_clear_protect(struct flash_bank *bank, int first, int last)
324 uint8_t select_block[3] = {0x0, 0x0, 0x0};
325 select_block[0] = fill_select_block(first, last);
326 return isc_set_register(bank, CMD_XSC_UNLOCK, select_block, 24, 0);
329 static int isc_set_protect(struct flash_bank *bank, int first, int last)
331 uint8_t wrpt[2] = {0xFF, 0xFF};
332 for (int i = first; i <= last; i++)
333 wrpt[0] &= ~(1 << i);
335 return isc_program_register(bank, CMD_XSC_DATA_WRPT, wrpt, 16, 0);
338 static int isc_erase_sectors(struct flash_bank *bank, int first, int last)
340 uint8_t select_block[3] = {0, 0, 0};
341 select_block[0] = fill_select_block(first, last);
342 int64_t timeout = SECTOR_ERASE_TIMEOUT_MS * (last - first + 1);
343 return isc_set_register(bank, CMD_ISC_ERASE, select_block, 24, timeout);
346 static int isc_adr_shift(struct flash_bank *bank, int adr)
348 uint8_t adr_buf[3];
349 h_u24_to_le(adr_buf, adr);
350 return isc_set_register(bank, CMD_ISC_ADDRESS_SHIFT, adr_buf, 24, 0);
353 static int isc_program_data_page(struct flash_bank *bank, const uint8_t *page_buf)
355 return isc_program_register(bank, CMD_ISC_DATA_SHIFT, page_buf, 8 * XCF_PAGE_SIZE, 100);
358 static void isc_data_read_out(struct flash_bank *bank, uint8_t *buffer, uint32_t count)
361 struct scan_field scan;
363 /* Do not change this code with isc_read_register() call because it needs
364 * transition to IDLE state before data retrieving. */
365 scan.check_mask = NULL;
366 scan.check_value = NULL;
367 scan.num_bits = 16;
368 scan.out_value = CMD_XSC_READ;
369 scan.in_value = NULL;
370 jtag_add_ir_scan(bank->target->tap, &scan, TAP_IDLE);
372 scan.num_bits = 8 * count;
373 scan.out_value = NULL;
374 scan.in_value = buffer;
375 jtag_add_dr_scan(bank->target->tap, 1, &scan, TAP_IDLE);
377 jtag_execute_queue();
380 static int isc_set_data_done(struct flash_bank *bank, int sector)
382 uint8_t done = 0xFF;
383 done &= ~(1 << sector);
384 return isc_program_register(bank, CMD_XSC_DATA_DONE, &done, 8, 100);
387 static void flip_u8(uint8_t *out, const uint8_t *in, int len)
389 for (int i = 0; i < len; i++)
390 out[i] = flip_u32(in[i], 8);
394 * Xilinx bin file contains simple fixed header for automatic bus width detection:
395 * 16 bytes of 0xFF
396 * 4 byte sync word 0xAA995566 or (bit reversed) 0x5599AA66 in MSC file
398 * Function presumes need of bit reversing if it can not exactly detects
399 * the opposite.
401 bool need_bit_reverse(const uint8_t *buffer)
403 const size_t L = 20;
404 uint8_t reference[L];
405 memset(reference, 0xFF, 16);
406 reference[16] = 0x55;
407 reference[17] = 0x99;
408 reference[18] = 0xAA;
409 reference[19] = 0x66;
411 if (0 == memcmp(reference, buffer, L))
412 return false;
413 else
414 return true;
418 * The page address to be programmed is determined by loading the
419 * internal ADDRESS Register using an ISC_ADDRESS_SHIFT instruction sequence.
420 * The page address automatically increments to the next 256-bit
421 * page address after each programming sequence until the last address
422 * in the 8 Mb block is reached. To continue programming the next block,
423 * the next 8 Mb block's starting address must be loaded into the
424 * internal ADDRESS register.
426 static int read_write_data(struct flash_bank *bank, const uint8_t *w_buffer,
427 uint8_t *r_buffer, bool write_flag, uint32_t offset, uint32_t count)
429 int dbg_count = count;
430 int dbg_written = 0;
431 int ret = ERROR_OK;
432 uint8_t *page_buf = malloc(XCF_PAGE_SIZE);
433 bool revbit = true;
434 isc_enter(bank);
436 if (offset % XCF_PAGE_SIZE != 0) {
437 ret = ERROR_FLASH_DST_BREAKS_ALIGNMENT;
438 goto EXIT;
441 if ((offset + count) > (uint32_t)(bank->num_sectors * XCF_DATA_SECTOR_SIZE)) {
442 ret = ERROR_FLASH_DST_OUT_OF_BANK;
443 goto EXIT;
446 if ((write_flag) && (0 == offset) && (count >= XCF_PAGE_SIZE))
447 revbit = need_bit_reverse(w_buffer);
449 while (count > 0) {
450 uint32_t sector_num = offset / XCF_DATA_SECTOR_SIZE;
451 uint32_t sector_offset = offset - sector_num * XCF_DATA_SECTOR_SIZE;
452 uint32_t sector_bytes = XCF_DATA_SECTOR_SIZE - sector_offset;
453 if (count < sector_bytes)
454 sector_bytes = count;
455 isc_adr_shift(bank, offset);
456 offset += sector_bytes;
457 count -= sector_bytes;
459 if (write_flag) {
460 while (sector_bytes > 0) {
461 int len;
463 if (sector_bytes < XCF_PAGE_SIZE) {
464 len = sector_bytes;
465 memset(page_buf, 0xFF, XCF_PAGE_SIZE);
466 } else
467 len = XCF_PAGE_SIZE;
469 if (revbit)
470 flip_u8(page_buf, w_buffer, len);
471 else
472 memcpy(page_buf, w_buffer, len);
474 w_buffer += len;
475 sector_bytes -= len;
476 ret = isc_program_data_page(bank, page_buf);
477 if (ERROR_OK != ret)
478 goto EXIT;
479 else {
480 LOG_DEBUG("written %d bytes from %d", dbg_written, dbg_count);
481 dbg_written += len;
484 } else {
485 isc_data_read_out(bank, r_buffer, sector_bytes);
486 flip_u8(r_buffer, r_buffer, sector_bytes);
487 r_buffer += sector_bytes;
491 /* Set 'done' flags for all data sectors because driver supports
492 * only single revision. */
493 if (write_flag) {
494 for (int i = 0; i < bank->num_sectors; i++) {
495 ret = isc_set_data_done(bank, i);
496 if (ERROR_OK != ret)
497 goto EXIT;
501 EXIT:
502 free(page_buf);
503 isc_leave(bank);
504 return ret;
507 static uint16_t isc_read_ccb(struct flash_bank *bank)
509 uint8_t ccb[2];
510 isc_read_register(bank, CMD_XSC_DATA_CCB, ccb, 16);
511 return le_to_h_u16(ccb);
514 static int gucr_num(const struct flash_bank *bank)
516 return bank->num_sectors;
519 static int sucr_num(const struct flash_bank *bank)
521 return bank->num_sectors + 1;
524 static int isc_program_ccb(struct flash_bank *bank, uint16_t ccb)
526 uint8_t buf[2];
527 h_u16_to_le(buf, ccb);
528 return isc_program_register(bank, CMD_XSC_DATA_CCB, buf, 16, 100);
531 static int isc_program_singe_revision_sucr(struct flash_bank *bank)
533 uint8_t sucr[2] = {0xFC, 0xFF};
534 return isc_program_register(bank, CMD_XSC_DATA_SUCR, sucr, 16, 100);
537 static int isc_program_single_revision_btc(struct flash_bank *bank)
539 uint8_t buf[4];
540 uint32_t btc = 0xFFFFFFFF;
541 btc &= ~0b1111;
542 btc |= ((bank->num_sectors - 1) << 2);
543 btc &= ~(1 << 4);
544 h_u32_to_le(buf, btc);
545 return isc_program_register(bank, CMD_XSC_DATA_BTC, buf, 32, 100);
548 static int fpga_configure(struct flash_bank *bank)
550 struct scan_field scan;
552 scan.check_mask = NULL;
553 scan.check_value = NULL;
554 scan.num_bits = 16;
555 scan.out_value = CMD_XSC_CONFIG;
556 scan.in_value = NULL;
557 jtag_add_ir_scan(bank->target->tap, &scan, TAP_IDLE);
558 jtag_execute_queue();
560 return ERROR_OK;
564 ******************************************************************************
565 * EXPORTED FUNCTIONS
566 ******************************************************************************
569 FLASH_BANK_COMMAND_HANDLER(xcf_flash_bank_command)
571 struct xcf_priv *priv;
573 priv = malloc(sizeof(struct xcf_priv));
574 if (priv == NULL) {
575 LOG_ERROR("no memory for flash bank info");
576 return ERROR_FAIL;
578 bank->driver_priv = priv;
579 priv->probed = false;
580 return ERROR_OK;
583 static int xcf_info(struct flash_bank *bank, char *buf, int buf_size)
585 const struct xcf_priv *priv = bank->driver_priv;
587 if (false == priv->probed) {
588 snprintf(buf, buf_size, "\nXCF flash bank not probed yet\n");
589 return ERROR_OK;
591 snprintf(buf, buf_size, "%s", product_name(bank));
592 return ERROR_OK;
595 static int xcf_probe(struct flash_bank *bank)
597 struct xcf_priv *priv = bank->driver_priv;
598 uint32_t id;
600 if (true == priv->probed)
601 free(bank->sectors);
602 priv->probed = false;
604 if (bank->target->tap == NULL) {
605 LOG_ERROR("Target has no JTAG tap");
606 return ERROR_FAIL;
609 /* check idcode and alloc memory for sector table */
610 if (!bank->target->tap->hasidcode)
611 return ERROR_FLASH_OPERATION_FAILED;
613 /* guess number of blocks using chip ID */
614 id = bank->target->tap->idcode;
615 switch (id & ID_MEANINGFUL_MASK) {
616 case ID_XCF08P:
617 bank->num_sectors = 1;
618 break;
619 case ID_XCF16P:
620 bank->num_sectors = 2;
621 break;
622 case ID_XCF32P:
623 bank->num_sectors = 4;
624 break;
625 default:
626 LOG_ERROR("Unknown flash device ID 0x%X", id);
627 return ERROR_FAIL;
630 bank->sectors = malloc(bank->num_sectors * sizeof(struct flash_sector));
631 if (NULL == bank->sectors) {
632 LOG_ERROR("No memory for sector table");
633 return ERROR_FAIL;
635 fill_sector_table(bank);
637 priv->probed = true;
638 /* REVISIT: Why is unchanged bank->driver_priv rewritten by same value? */
639 bank->driver_priv = priv;
641 LOG_INFO("product name: %s", product_name(bank));
642 LOG_INFO("device id = 0x%X ", bank->target->tap->idcode);
643 LOG_INFO("flash size = %d configuration bits",
644 bank->num_sectors * XCF_DATA_SECTOR_SIZE * 8);
645 LOG_INFO("number of sectors = %d", bank->num_sectors);
647 return ERROR_OK;
650 static int xcf_auto_probe(struct flash_bank *bank)
652 struct xcf_priv *priv = bank->driver_priv;
654 if (true == priv->probed)
655 return ERROR_OK;
656 else
657 return xcf_probe(bank);
660 static int xcf_protect_check(struct flash_bank *bank)
662 uint8_t wrpt[2];
664 isc_enter(bank);
665 isc_read_register(bank, CMD_XSC_DATA_WRPT, wrpt, 16);
666 isc_leave(bank);
668 for (int i = 0; i < bank->num_sectors; i++)
669 bank->sectors[i].is_protected = sector_state(wrpt[0], i);
671 return ERROR_OK;
674 static int xcf_erase_check(struct flash_bank *bank)
676 uint8_t blankreg;
677 struct scan_field scan;
679 isc_enter(bank);
681 /* Do not change this code with isc_read_register() call because it needs
682 * transition to IDLE state and pause before data retrieving. */
683 scan.check_mask = NULL;
684 scan.check_value = NULL;
685 scan.num_bits = 16;
686 scan.out_value = CMD_XSC_BLANK_CHECK;
687 scan.in_value = NULL;
688 jtag_add_ir_scan(bank->target->tap, &scan, TAP_IDLE);
689 jtag_execute_queue();
690 alive_sleep(500); /* device needs at least 0.5s to self check */
692 scan.num_bits = 8;
693 scan.in_value = &blankreg;
694 jtag_add_dr_scan(bank->target->tap, 1, &scan, TAP_IDLE);
695 jtag_execute_queue();
697 isc_leave(bank);
699 for (int i = 0; i < bank->num_sectors; i++)
700 bank->sectors[i].is_erased = sector_state(blankreg, i);
702 return ERROR_OK;
705 static int xcf_erase(struct flash_bank *bank, int first, int last)
707 if ((first >= bank->num_sectors)
708 || (last >= bank->num_sectors)
709 || (last < first))
710 return ERROR_FLASH_SECTOR_INVALID;
711 else {
712 isc_enter(bank);
713 isc_clear_protect(bank, first, last);
714 int ret = isc_erase_sectors(bank, first, last);
715 isc_leave(bank);
716 return ret;
720 static int xcf_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
722 return read_write_data(bank, NULL, buffer, false, offset, count);
725 static int xcf_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset,
726 uint32_t count)
728 return read_write_data(bank, buffer, NULL, true, offset, count);
731 static int xcf_protect(struct flash_bank *bank, int set, int first, int last)
733 int ret;
735 isc_enter(bank);
736 if (set)
737 ret = isc_set_protect(bank, first, last);
738 else {
739 /* write protection may be removed only with following erase */
740 isc_clear_protect(bank, first, last);
741 ret = isc_erase_sectors(bank, first, last);
743 isc_leave(bank);
745 return ret;
748 COMMAND_HANDLER(xcf_handle_ccb_command) {
750 if (!((CMD_ARGC == 1) || (CMD_ARGC == 5)))
751 return ERROR_COMMAND_SYNTAX_ERROR;
753 struct flash_bank *bank;
754 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
755 if (ERROR_OK != retval)
756 return retval;
758 uint16_t ccb = 0xFFFF;
759 isc_enter(bank);
760 uint16_t old_ccb = isc_read_ccb(bank);
761 isc_leave(bank);
763 if (CMD_ARGC == 1) {
764 LOG_INFO("current CCB = 0x%X", old_ccb);
765 return ERROR_OK;
766 } else {
767 /* skip over flash bank */
768 CMD_ARGC--;
769 CMD_ARGV++;
770 while (CMD_ARGC) {
771 if (strcmp("external", CMD_ARGV[0]) == 0)
772 ccb |= (1 << 0);
773 else if (strcmp("internal", CMD_ARGV[0]) == 0)
774 ccb &= ~(1 << 0);
775 else if (strcmp("serial", CMD_ARGV[0]) == 0)
776 ccb |= (3 << 1);
777 else if (strcmp("parallel", CMD_ARGV[0]) == 0)
778 ccb &= ~(3 << 1);
779 else if (strcmp("slave", CMD_ARGV[0]) == 0)
780 ccb |= (1 << 3);
781 else if (strcmp("master", CMD_ARGV[0]) == 0)
782 ccb &= ~(1 << 3);
783 else if (strcmp("40", CMD_ARGV[0]) == 0)
784 ccb |= (3 << 4);
785 else if (strcmp("20", CMD_ARGV[0]) == 0)
786 ccb &= ~(1 << 5);
787 else
788 return ERROR_COMMAND_SYNTAX_ERROR;
789 CMD_ARGC--;
790 CMD_ARGV++;
793 isc_enter(bank);
794 int sector;
796 /* GUCR sector */
797 sector = gucr_num(bank);
798 isc_clear_protect(bank, sector, sector);
799 int ret = isc_erase_sectors(bank, sector, sector);
800 if (ERROR_OK != ret)
801 goto EXIT;
802 ret = isc_program_ccb(bank, ccb);
803 if (ERROR_OK != ret)
804 goto EXIT;
805 ret = isc_program_single_revision_btc(bank);
806 if (ERROR_OK != ret)
807 goto EXIT;
808 ret = isc_set_data_done(bank, sector);
809 if (ERROR_OK != ret)
810 goto EXIT;
812 /* SUCR sector */
813 sector = sucr_num(bank);
814 isc_clear_protect(bank, sector, sector);
815 ret = isc_erase_sectors(bank, sector, sector);
816 if (ERROR_OK != ret)
817 goto EXIT;
818 ret = isc_program_singe_revision_sucr(bank);
819 if (ERROR_OK != ret)
820 goto EXIT;
821 ret = isc_set_data_done(bank, sector);
822 if (ERROR_OK != ret)
823 goto EXIT;
825 EXIT:
826 isc_leave(bank);
827 return ret;
831 COMMAND_HANDLER(xcf_handle_configure_command) {
833 if (CMD_ARGC != 1)
834 return ERROR_COMMAND_SYNTAX_ERROR;
836 struct flash_bank *bank;
837 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
838 if (ERROR_OK != retval)
839 return retval;
841 return fpga_configure(bank);
844 static const struct command_registration xcf_exec_command_handlers[] = {
846 .name = "configure",
847 .handler = xcf_handle_configure_command,
848 .mode = COMMAND_EXEC,
849 .usage = "bank_id",
850 .help = "Initiate FPGA loading procedure."
853 .name = "ccb",
854 .handler = xcf_handle_ccb_command,
855 .mode = COMMAND_EXEC,
856 .usage = "bank_id [('external'|'internal') "
857 "('serial'|'parallel') "
858 "('slave'|'master') "
859 "('40'|'20')]",
860 .help = "Write CCB register with supplied options and (silently) BTC "
861 "register with single revision options. Display current "
862 "CCB value when only bank_id supplied. "
863 "Following options available: "
864 "1) external or internal clock source; "
865 "2) serial or parallel bus mode; "
866 "3) slave or master mode; "
867 "4) clock frequency in MHz for internal clock in master mode;"
869 COMMAND_REGISTRATION_DONE
872 static const struct command_registration xcf_command_handlers[] = {
874 .name = "xcf",
875 .mode = COMMAND_ANY,
876 .help = "Xilinx platform flash command group",
877 .usage = "",
878 .chain = xcf_exec_command_handlers
880 COMMAND_REGISTRATION_DONE
883 const struct flash_driver xcf_flash = {
884 .name = "xcf",
885 .usage = NULL,
886 .commands = xcf_command_handlers,
887 .flash_bank_command = xcf_flash_bank_command,
888 .erase = xcf_erase,
889 .protect = xcf_protect,
890 .write = xcf_write,
891 .read = xcf_read,
892 .probe = xcf_probe,
893 .auto_probe = xcf_auto_probe,
894 .erase_check = xcf_erase_check,
895 .protect_check = xcf_protect_check,
896 .info = xcf_info,
897 .free_driver_priv = default_flash_free_driver_priv,