1 /***************************************************************************
2 * Copyright (C) 2016 by Uladzimir Pylinski aka barthess *
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, see <http://www.gnu.org/licenses/>. *
17 ***************************************************************************/
26 #include <jtag/jtag.h>
27 #include <helper/time_support.h>
30 ******************************************************************************
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
[] = {
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 ******************************************************************************
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 ******************************************************************************
94 ******************************************************************************
97 static const char *product_name(const struct flash_bank
*bank
)
100 switch (bank
->target
->tap
->idcode
& ID_MEANINGFUL_MASK
) {
102 return xcf_name_list
[0];
104 return xcf_name_list
[1];
106 return xcf_name_list
[2];
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. */
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
;
135 struct scan_field scan
;
137 scan
.check_mask
= NULL
;
138 scan
.check_value
= NULL
;
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;
154 static int isc_enter(struct flash_bank
*bank
)
157 struct xcf_status status
= read_status(bank
);
159 if (true == status
.isc_mode
)
162 struct scan_field scan
;
164 scan
.check_mask
= NULL
;
165 scan
.check_value
= NULL
;
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
;
183 static int isc_leave(struct flash_bank
*bank
)
186 struct xcf_status status
= read_status(bank
);
188 if (false == status
.isc_mode
)
191 struct scan_field scan
;
193 scan
.check_mask
= NULL
;
194 scan
.check_value
= NULL
;
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
;
213 static int sector_state(uint8_t wrpt
, int sector
)
215 if (((wrpt
>> sector
) & 1) == 1)
221 static uint8_t fill_select_block(int first
, int last
)
224 for (int i
= first
; i
<= last
; i
++)
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
;
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
)
253 int64_t t0
= timeval_ms();
257 isc_read_register(bank
, CMD_XSC_OP_STATUS
, &isc_default
, 8);
258 if (((isc_default
>> 2) & 1) == 1)
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
;
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
);
286 return jtag_execute_queue();
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
;
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
);
312 scan
.out_value
= CMD_ISC_PROGRAM
;
313 scan
.in_value
= NULL
;
314 jtag_add_ir_scan(bank
->target
->tap
, &scan
, TAP_IDLE
);
317 return jtag_execute_queue();
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
)
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
;
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
)
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:
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
401 bool need_bit_reverse(const uint8_t *buffer
)
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
))
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
;
432 uint8_t *page_buf
= malloc(XCF_PAGE_SIZE
);
436 if (offset
% XCF_PAGE_SIZE
!= 0) {
437 ret
= ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
441 if ((offset
+ count
) > (uint32_t)(bank
->num_sectors
* XCF_DATA_SECTOR_SIZE
)) {
442 ret
= ERROR_FLASH_DST_OUT_OF_BANK
;
446 if ((write_flag
) && (0 == offset
) && (count
>= XCF_PAGE_SIZE
))
447 revbit
= need_bit_reverse(w_buffer
);
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
;
460 while (sector_bytes
> 0) {
463 if (sector_bytes
< XCF_PAGE_SIZE
) {
465 memset(page_buf
, 0xFF, XCF_PAGE_SIZE
);
470 flip_u8(page_buf
, w_buffer
, len
);
472 memcpy(page_buf
, w_buffer
, len
);
476 ret
= isc_program_data_page(bank
, page_buf
);
480 LOG_DEBUG("written %d bytes from %d", dbg_written
, dbg_count
);
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. */
494 for (int i
= 0; i
< bank
->num_sectors
; i
++) {
495 ret
= isc_set_data_done(bank
, i
);
507 static uint16_t isc_read_ccb(struct flash_bank
*bank
)
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
)
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
)
540 uint32_t btc
= 0xFFFFFFFF;
542 btc
|= ((bank
->num_sectors
- 1) << 2);
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
;
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();
564 ******************************************************************************
566 ******************************************************************************
569 FLASH_BANK_COMMAND_HANDLER(xcf_flash_bank_command
)
571 struct xcf_priv
*priv
;
573 priv
= malloc(sizeof(struct xcf_priv
));
575 LOG_ERROR("no memory for flash bank info");
578 bank
->driver_priv
= priv
;
579 priv
->probed
= false;
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");
591 snprintf(buf
, buf_size
, "%s", product_name(bank
));
595 static int xcf_probe(struct flash_bank
*bank
)
597 struct xcf_priv
*priv
= bank
->driver_priv
;
600 if (true == priv
->probed
)
602 priv
->probed
= false;
604 if (bank
->target
->tap
== NULL
) {
605 LOG_ERROR("Target has no JTAG tap");
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
) {
617 bank
->num_sectors
= 1;
620 bank
->num_sectors
= 2;
623 bank
->num_sectors
= 4;
626 LOG_ERROR("Unknown flash device ID 0x%X", id
);
630 bank
->sectors
= malloc(bank
->num_sectors
* sizeof(struct flash_sector
));
631 if (NULL
== bank
->sectors
) {
632 LOG_ERROR("No memory for sector table");
635 fill_sector_table(bank
);
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
);
650 static int xcf_auto_probe(struct flash_bank
*bank
)
652 struct xcf_priv
*priv
= bank
->driver_priv
;
654 if (true == priv
->probed
)
657 return xcf_probe(bank
);
660 static int xcf_protect_check(struct flash_bank
*bank
)
665 isc_read_register(bank
, CMD_XSC_DATA_WRPT
, wrpt
, 16);
668 for (int i
= 0; i
< bank
->num_sectors
; i
++)
669 bank
->sectors
[i
].is_protected
= sector_state(wrpt
[0], i
);
674 static int xcf_erase_check(struct flash_bank
*bank
)
677 struct scan_field scan
;
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
;
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 */
693 scan
.in_value
= &blankreg
;
694 jtag_add_dr_scan(bank
->target
->tap
, 1, &scan
, TAP_IDLE
);
695 jtag_execute_queue();
699 for (int i
= 0; i
< bank
->num_sectors
; i
++)
700 bank
->sectors
[i
].is_erased
= sector_state(blankreg
, i
);
705 static int xcf_erase(struct flash_bank
*bank
, int first
, int last
)
707 if ((first
>= bank
->num_sectors
)
708 || (last
>= bank
->num_sectors
)
710 return ERROR_FLASH_SECTOR_INVALID
;
713 isc_clear_protect(bank
, first
, last
);
714 int ret
= isc_erase_sectors(bank
, first
, last
);
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
,
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
)
737 ret
= isc_set_protect(bank
, first
, last
);
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
);
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
)
758 uint16_t ccb
= 0xFFFF;
760 uint16_t old_ccb
= isc_read_ccb(bank
);
764 LOG_INFO("current CCB = 0x%X", old_ccb
);
767 /* skip over flash bank */
771 if (strcmp("external", CMD_ARGV
[0]) == 0)
773 else if (strcmp("internal", CMD_ARGV
[0]) == 0)
775 else if (strcmp("serial", CMD_ARGV
[0]) == 0)
777 else if (strcmp("parallel", CMD_ARGV
[0]) == 0)
779 else if (strcmp("slave", CMD_ARGV
[0]) == 0)
781 else if (strcmp("master", CMD_ARGV
[0]) == 0)
783 else if (strcmp("40", CMD_ARGV
[0]) == 0)
785 else if (strcmp("20", CMD_ARGV
[0]) == 0)
788 return ERROR_COMMAND_SYNTAX_ERROR
;
797 sector
= gucr_num(bank
);
798 isc_clear_protect(bank
, sector
, sector
);
799 int ret
= isc_erase_sectors(bank
, sector
, sector
);
802 ret
= isc_program_ccb(bank
, ccb
);
805 ret
= isc_program_single_revision_btc(bank
);
808 ret
= isc_set_data_done(bank
, sector
);
813 sector
= sucr_num(bank
);
814 isc_clear_protect(bank
, sector
, sector
);
815 ret
= isc_erase_sectors(bank
, sector
, sector
);
818 ret
= isc_program_singe_revision_sucr(bank
);
821 ret
= isc_set_data_done(bank
, sector
);
831 COMMAND_HANDLER(xcf_handle_configure_command
) {
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
)
841 return fpga_configure(bank
);
844 static const struct command_registration xcf_exec_command_handlers
[] = {
847 .handler
= xcf_handle_configure_command
,
848 .mode
= COMMAND_EXEC
,
850 .help
= "Initiate FPGA loading procedure."
854 .handler
= xcf_handle_ccb_command
,
855 .mode
= COMMAND_EXEC
,
856 .usage
= "bank_id [('external'|'internal') "
857 "('serial'|'parallel') "
858 "('slave'|'master') "
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
[] = {
876 .help
= "Xilinx platform flash command group",
878 .chain
= xcf_exec_command_handlers
880 COMMAND_REGISTRATION_DONE
883 const struct flash_driver xcf_flash
= {
886 .commands
= xcf_command_handlers
,
887 .flash_bank_command
= xcf_flash_bank_command
,
889 .protect
= xcf_protect
,
893 .auto_probe
= xcf_auto_probe
,
894 .erase_check
= xcf_erase_check
,
895 .protect_check
= xcf_protect_check
,
897 .free_driver_priv
= default_flash_free_driver_priv
,