1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 /***************************************************************************
4 * Copyright (C) 2016 by Uladzimir Pylinski aka barthess *
6 ***************************************************************************/
15 #include <jtag/jtag.h>
16 #include <helper/time_support.h>
19 ******************************************************************************
21 ******************************************************************************
24 #define SECTOR_ERASE_TIMEOUT_MS (35 * 1000)
26 #define XCF_PAGE_SIZE 32
27 #define XCF_DATA_SECTOR_SIZE (1024 * 1024)
29 #define ID_XCF01S 0x05044093
30 #define ID_XCF02S 0x05045093
31 #define ID_XCF04S 0x05046093
32 #define ID_XCF08P 0x05057093
33 #define ID_XCF16P 0x05058093
34 #define ID_XCF32P 0x05059093
35 #define ID_MEANINGFUL_MASK 0x0FFFFFFF
37 static const char * const xcf_name_list
[] = {
49 bool isc_error
; /* false == OK, true == error */
50 bool prog_error
; /* false == OK, true == error */
51 bool prog_busy
; /* false == idle, true == busy */
52 bool isc_mode
; /* false == normal mode, true == ISC mode */
56 ******************************************************************************
58 ******************************************************************************
60 static const uint8_t cmd_bypass
[2] = {0xFF, 0xFF};
62 static const uint8_t cmd_isc_address_shift
[2] = {0xEB, 0x00};
63 static const uint8_t cmd_isc_data_shift
[2] = {0xED, 0x00};
64 static const uint8_t cmd_isc_disable
[2] = {0xF0, 0x00};
65 static const uint8_t cmd_isc_enable
[2] = {0xE8, 0x00};
66 static const uint8_t cmd_isc_erase
[2] = {0xEC, 0x00};
67 static const uint8_t cmd_isc_program
[2] = {0xEA, 0x00};
69 static const uint8_t cmd_xsc_blank_check
[2] = {0x0D, 0x00};
70 static const uint8_t cmd_xsc_config
[2] = {0xEE, 0x00};
71 static const uint8_t cmd_xsc_data_btc
[2] = {0xF2, 0x00};
72 static const uint8_t cmd_xsc_data_ccb
[2] = {0x0C, 0x00};
73 static const uint8_t cmd_xsc_data_done
[2] = {0x09, 0x00};
74 static const uint8_t cmd_xsc_data_sucr
[2] = {0x0E, 0x00};
75 static const uint8_t cmd_xsc_data_wrpt
[2] = {0xF7, 0x00};
76 static const uint8_t cmd_xsc_op_status
[2] = {0xE3, 0x00};
77 static const uint8_t cmd_xsc_read
[2] = {0xEF, 0x00};
78 static const uint8_t cmd_xsc_unlock
[2] = {0x55, 0xAA};
81 ******************************************************************************
83 ******************************************************************************
86 static const char *product_name(const struct flash_bank
*bank
)
89 switch (bank
->target
->tap
->idcode
& ID_MEANINGFUL_MASK
) {
91 return xcf_name_list
[0];
93 return xcf_name_list
[1];
95 return xcf_name_list
[2];
97 return xcf_name_list
[3];
101 static void fill_sector_table(struct flash_bank
*bank
)
103 /* Note: is_erased and is_protected fields must be set here to an unknown
104 * state, they will be correctly filled from other API calls. */
106 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++) {
107 bank
->sectors
[i
].is_erased
= -1;
108 bank
->sectors
[i
].is_protected
= -1;
110 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++) {
111 bank
->sectors
[i
].size
= XCF_DATA_SECTOR_SIZE
;
112 bank
->sectors
[i
].offset
= i
* XCF_DATA_SECTOR_SIZE
;
115 bank
->size
= bank
->num_sectors
* XCF_DATA_SECTOR_SIZE
;
118 static struct xcf_status
read_status(struct flash_bank
*bank
)
120 struct xcf_status ret
;
122 struct scan_field scan
;
124 scan
.check_mask
= NULL
;
125 scan
.check_value
= NULL
;
127 scan
.out_value
= cmd_bypass
;
128 scan
.in_value
= irdata
;
130 jtag_add_ir_scan(bank
->target
->tap
, &scan
, TAP_IDLE
);
131 jtag_execute_queue();
133 ret
.isc_error
= ((irdata
[0] >> 7) & 3) == 0b01;
134 ret
.prog_error
= ((irdata
[0] >> 5) & 3) == 0b01;
135 ret
.prog_busy
= ((irdata
[0] >> 4) & 1) == 0;
136 ret
.isc_mode
= ((irdata
[0] >> 3) & 1) == 1;
141 static int isc_enter(struct flash_bank
*bank
)
144 struct xcf_status status
= read_status(bank
);
146 if (true == status
.isc_mode
)
149 struct scan_field scan
;
151 scan
.check_mask
= NULL
;
152 scan
.check_value
= NULL
;
154 scan
.out_value
= cmd_isc_enable
;
155 scan
.in_value
= NULL
;
157 jtag_add_ir_scan(bank
->target
->tap
, &scan
, TAP_IDLE
);
158 jtag_execute_queue();
160 status
= read_status(bank
);
161 if (!status
.isc_mode
) {
162 LOG_ERROR("*** XCF: FAILED to enter ISC mode");
163 return ERROR_FLASH_OPERATION_FAILED
;
170 static int isc_leave(struct flash_bank
*bank
)
173 struct xcf_status status
= read_status(bank
);
175 if (!status
.isc_mode
)
178 struct scan_field scan
;
180 scan
.check_mask
= NULL
;
181 scan
.check_value
= NULL
;
183 scan
.out_value
= cmd_isc_disable
;
184 scan
.in_value
= NULL
;
186 jtag_add_ir_scan(bank
->target
->tap
, &scan
, TAP_IDLE
);
187 jtag_execute_queue();
188 alive_sleep(1); /* device needs 50 uS to leave ISC mode */
190 status
= read_status(bank
);
191 if (status
.isc_mode
) {
192 LOG_ERROR("*** XCF: FAILED to leave ISC mode");
193 return ERROR_FLASH_OPERATION_FAILED
;
200 static int sector_state(uint8_t wrpt
, int sector
)
202 if (((wrpt
>> sector
) & 1) == 1)
208 static uint8_t fill_select_block(unsigned int first
, unsigned int last
)
211 for (unsigned int i
= first
; i
<= last
; i
++)
216 static int isc_read_register(struct flash_bank
*bank
, const uint8_t *cmd
,
217 uint8_t *data_buf
, int num_bits
)
219 struct scan_field scan
;
221 scan
.check_mask
= NULL
;
222 scan
.check_value
= NULL
;
223 scan
.out_value
= cmd
;
224 scan
.in_value
= NULL
;
226 jtag_add_ir_scan(bank
->target
->tap
, &scan
, TAP_DRSHIFT
);
228 scan
.out_value
= NULL
;
229 scan
.in_value
= data_buf
;
230 scan
.num_bits
= num_bits
;
231 jtag_add_dr_scan(bank
->target
->tap
, 1, &scan
, TAP_IDLE
);
233 return jtag_execute_queue();
236 static int isc_wait_erase_program(struct flash_bank
*bank
, int64_t timeout_ms
)
240 int64_t t0
= timeval_ms();
244 isc_read_register(bank
, cmd_xsc_op_status
, &isc_default
, 8);
245 if (((isc_default
>> 2) & 1) == 1)
247 dt
= timeval_ms() - t0
;
248 } while (dt
<= timeout_ms
);
249 return ERROR_FLASH_OPERATION_FAILED
;
253 * helper function for procedures without program jtag command at the end
255 static int isc_set_register(struct flash_bank
*bank
, const uint8_t *cmd
,
256 const uint8_t *data_buf
, int num_bits
, int64_t timeout_ms
)
258 struct scan_field scan
;
260 scan
.check_mask
= NULL
;
261 scan
.check_value
= NULL
;
263 scan
.out_value
= cmd
;
264 scan
.in_value
= NULL
;
265 jtag_add_ir_scan(bank
->target
->tap
, &scan
, TAP_DRSHIFT
);
267 scan
.num_bits
= num_bits
;
268 scan
.out_value
= data_buf
;
269 scan
.in_value
= NULL
;
270 jtag_add_dr_scan(bank
->target
->tap
, 1, &scan
, TAP_IDLE
);
273 return jtag_execute_queue();
275 return isc_wait_erase_program(bank
, timeout_ms
);
279 * helper function for procedures required program jtag command at the end
281 static int isc_program_register(struct flash_bank
*bank
, const uint8_t *cmd
,
282 const uint8_t *data_buf
, int num_bits
, int64_t timeout_ms
)
284 struct scan_field scan
;
286 scan
.check_mask
= NULL
;
287 scan
.check_value
= NULL
;
289 scan
.out_value
= cmd
;
290 scan
.in_value
= NULL
;
291 jtag_add_ir_scan(bank
->target
->tap
, &scan
, TAP_DRSHIFT
);
293 scan
.num_bits
= num_bits
;
294 scan
.out_value
= data_buf
;
295 scan
.in_value
= NULL
;
296 jtag_add_dr_scan(bank
->target
->tap
, 1, &scan
, TAP_IRSHIFT
);
299 scan
.out_value
= cmd_isc_program
;
300 scan
.in_value
= NULL
;
301 jtag_add_ir_scan(bank
->target
->tap
, &scan
, TAP_IDLE
);
304 return jtag_execute_queue();
306 return isc_wait_erase_program(bank
, timeout_ms
);
309 static int isc_clear_protect(struct flash_bank
*bank
, unsigned int first
,
312 uint8_t select_block
[3] = {0x0, 0x0, 0x0};
313 select_block
[0] = fill_select_block(first
, last
);
314 return isc_set_register(bank
, cmd_xsc_unlock
, select_block
, 24, 0);
317 static int isc_set_protect(struct flash_bank
*bank
, unsigned int first
,
320 uint8_t wrpt
[2] = {0xFF, 0xFF};
321 for (unsigned int i
= first
; i
<= last
; i
++)
322 wrpt
[0] &= ~(1 << i
);
324 return isc_program_register(bank
, cmd_xsc_data_wrpt
, wrpt
, 16, 0);
327 static int isc_erase_sectors(struct flash_bank
*bank
, unsigned int first
,
330 uint8_t select_block
[3] = {0, 0, 0};
331 select_block
[0] = fill_select_block(first
, last
);
332 int64_t timeout
= SECTOR_ERASE_TIMEOUT_MS
* (last
- first
+ 1);
333 return isc_set_register(bank
, cmd_isc_erase
, select_block
, 24, timeout
);
336 static int isc_adr_shift(struct flash_bank
*bank
, int adr
)
339 h_u24_to_le(adr_buf
, adr
);
340 return isc_set_register(bank
, cmd_isc_address_shift
, adr_buf
, 24, 0);
343 static int isc_program_data_page(struct flash_bank
*bank
, const uint8_t *page_buf
)
345 return isc_program_register(bank
, cmd_isc_data_shift
, page_buf
, 8 * XCF_PAGE_SIZE
, 100);
348 static void isc_data_read_out(struct flash_bank
*bank
, uint8_t *buffer
, uint32_t count
)
351 struct scan_field scan
;
353 /* Do not change this code with isc_read_register() call because it needs
354 * transition to IDLE state before data retrieving. */
355 scan
.check_mask
= NULL
;
356 scan
.check_value
= NULL
;
358 scan
.out_value
= cmd_xsc_read
;
359 scan
.in_value
= NULL
;
360 jtag_add_ir_scan(bank
->target
->tap
, &scan
, TAP_IDLE
);
362 scan
.num_bits
= 8 * count
;
363 scan
.out_value
= NULL
;
364 scan
.in_value
= buffer
;
365 jtag_add_dr_scan(bank
->target
->tap
, 1, &scan
, TAP_IDLE
);
367 jtag_execute_queue();
370 static int isc_set_data_done(struct flash_bank
*bank
, int sector
)
373 done
&= ~(1 << sector
);
374 return isc_program_register(bank
, cmd_xsc_data_done
, &done
, 8, 100);
377 static void flip_u8(uint8_t *out
, const uint8_t *in
, int len
)
379 for (int i
= 0; i
< len
; i
++)
380 out
[i
] = flip_u32(in
[i
], 8);
384 * Xilinx bin file contains simple fixed header for automatic bus width detection:
386 * 4 byte sync word 0xAA995566 or (bit reversed) 0x5599AA66 in MSC file
388 * Function presumes need of bit reversing if it can not exactly detects
391 static bool need_bit_reverse(const uint8_t *buffer
)
394 uint8_t reference
[L
];
395 memset(reference
, 0xFF, 16);
396 reference
[16] = 0x55;
397 reference
[17] = 0x99;
398 reference
[18] = 0xAA;
399 reference
[19] = 0x66;
401 if (memcmp(reference
, buffer
, L
) == 0)
408 * The page address to be programmed is determined by loading the
409 * internal ADDRESS Register using an ISC_ADDRESS_SHIFT instruction sequence.
410 * The page address automatically increments to the next 256-bit
411 * page address after each programming sequence until the last address
412 * in the 8 Mb block is reached. To continue programming the next block,
413 * the next 8 Mb block's starting address must be loaded into the
414 * internal ADDRESS register.
416 static int read_write_data(struct flash_bank
*bank
, const uint8_t *w_buffer
,
417 uint8_t *r_buffer
, bool write_flag
, uint32_t offset
, uint32_t count
)
419 int dbg_count
= count
;
422 uint8_t *page_buf
= malloc(XCF_PAGE_SIZE
);
426 if (offset
% XCF_PAGE_SIZE
!= 0) {
427 ret
= ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
431 if ((offset
+ count
) > (bank
->num_sectors
* XCF_DATA_SECTOR_SIZE
)) {
432 ret
= ERROR_FLASH_DST_OUT_OF_BANK
;
436 if ((write_flag
) && (offset
== 0) && (count
>= XCF_PAGE_SIZE
))
437 revbit
= need_bit_reverse(w_buffer
);
440 uint32_t sector_num
= offset
/ XCF_DATA_SECTOR_SIZE
;
441 uint32_t sector_offset
= offset
- sector_num
* XCF_DATA_SECTOR_SIZE
;
442 uint32_t sector_bytes
= XCF_DATA_SECTOR_SIZE
- sector_offset
;
443 if (count
< sector_bytes
)
444 sector_bytes
= count
;
445 isc_adr_shift(bank
, offset
);
446 offset
+= sector_bytes
;
447 count
-= sector_bytes
;
450 while (sector_bytes
> 0) {
453 if (sector_bytes
< XCF_PAGE_SIZE
) {
455 memset(page_buf
, 0xFF, XCF_PAGE_SIZE
);
460 flip_u8(page_buf
, w_buffer
, len
);
462 memcpy(page_buf
, w_buffer
, len
);
466 ret
= isc_program_data_page(bank
, page_buf
);
470 LOG_DEBUG("written %d bytes from %d", dbg_written
, dbg_count
);
475 isc_data_read_out(bank
, r_buffer
, sector_bytes
);
476 flip_u8(r_buffer
, r_buffer
, sector_bytes
);
477 r_buffer
+= sector_bytes
;
481 /* Set 'done' flags for all data sectors because driver supports
482 * only single revision. */
484 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++) {
485 ret
= isc_set_data_done(bank
, i
);
497 static uint16_t isc_read_ccb(struct flash_bank
*bank
)
500 isc_read_register(bank
, cmd_xsc_data_ccb
, ccb
, 16);
501 return le_to_h_u16(ccb
);
504 static unsigned int gucr_num(const struct flash_bank
*bank
)
506 return bank
->num_sectors
;
509 static unsigned int sucr_num(const struct flash_bank
*bank
)
511 return bank
->num_sectors
+ 1;
514 static int isc_program_ccb(struct flash_bank
*bank
, uint16_t ccb
)
517 h_u16_to_le(buf
, ccb
);
518 return isc_program_register(bank
, cmd_xsc_data_ccb
, buf
, 16, 100);
521 static int isc_program_singe_revision_sucr(struct flash_bank
*bank
)
523 uint8_t sucr
[2] = {0xFC, 0xFF};
524 return isc_program_register(bank
, cmd_xsc_data_sucr
, sucr
, 16, 100);
527 static int isc_program_single_revision_btc(struct flash_bank
*bank
)
530 uint32_t btc
= 0xFFFFFFFF;
532 btc
|= ((bank
->num_sectors
- 1) << 2);
534 h_u32_to_le(buf
, btc
);
535 return isc_program_register(bank
, cmd_xsc_data_btc
, buf
, 32, 100);
538 static int fpga_configure(struct flash_bank
*bank
)
540 struct scan_field scan
;
542 scan
.check_mask
= NULL
;
543 scan
.check_value
= NULL
;
545 scan
.out_value
= cmd_xsc_config
;
546 scan
.in_value
= NULL
;
547 jtag_add_ir_scan(bank
->target
->tap
, &scan
, TAP_IDLE
);
548 jtag_execute_queue();
554 ******************************************************************************
556 ******************************************************************************
559 FLASH_BANK_COMMAND_HANDLER(xcf_flash_bank_command
)
561 struct xcf_priv
*priv
;
563 priv
= malloc(sizeof(struct xcf_priv
));
565 LOG_ERROR("no memory for flash bank info");
568 bank
->driver_priv
= priv
;
569 priv
->probed
= false;
573 static int xcf_info(struct flash_bank
*bank
, struct command_invocation
*cmd
)
575 const struct xcf_priv
*priv
= bank
->driver_priv
;
578 command_print_sameline(cmd
, "\nXCF flash bank not probed yet\n");
581 command_print_sameline(cmd
, "%s", product_name(bank
));
585 static int xcf_probe(struct flash_bank
*bank
)
587 struct xcf_priv
*priv
= bank
->driver_priv
;
592 priv
->probed
= false;
594 if (!bank
->target
->tap
) {
595 LOG_ERROR("Target has no JTAG tap");
599 /* check idcode and alloc memory for sector table */
600 if (!bank
->target
->tap
->hasidcode
)
601 return ERROR_FLASH_OPERATION_FAILED
;
603 /* guess number of blocks using chip ID */
604 id
= bank
->target
->tap
->idcode
;
605 switch (id
& ID_MEANINGFUL_MASK
) {
607 bank
->num_sectors
= 1;
610 bank
->num_sectors
= 2;
613 bank
->num_sectors
= 4;
616 LOG_ERROR("Unknown flash device ID 0x%" PRIX32
, id
);
620 bank
->sectors
= malloc(bank
->num_sectors
* sizeof(struct flash_sector
));
621 if (!bank
->sectors
) {
622 LOG_ERROR("No memory for sector table");
625 fill_sector_table(bank
);
628 /* REVISIT: Why is unchanged bank->driver_priv rewritten by same value? */
629 bank
->driver_priv
= priv
;
631 LOG_INFO("product name: %s", product_name(bank
));
632 LOG_INFO("device id = 0x%" PRIX32
, bank
->target
->tap
->idcode
);
633 LOG_INFO("flash size = %d configuration bits",
634 bank
->num_sectors
* XCF_DATA_SECTOR_SIZE
* 8);
635 LOG_INFO("number of sectors = %u", bank
->num_sectors
);
640 static int xcf_auto_probe(struct flash_bank
*bank
)
642 struct xcf_priv
*priv
= bank
->driver_priv
;
647 return xcf_probe(bank
);
650 static int xcf_protect_check(struct flash_bank
*bank
)
655 isc_read_register(bank
, cmd_xsc_data_wrpt
, wrpt
, 16);
658 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++)
659 bank
->sectors
[i
].is_protected
= sector_state(wrpt
[0], i
);
664 static int xcf_erase_check(struct flash_bank
*bank
)
667 struct scan_field scan
;
671 /* Do not change this code with isc_read_register() call because it needs
672 * transition to IDLE state and pause before data retrieving. */
673 scan
.check_mask
= NULL
;
674 scan
.check_value
= NULL
;
676 scan
.out_value
= cmd_xsc_blank_check
;
677 scan
.in_value
= NULL
;
678 jtag_add_ir_scan(bank
->target
->tap
, &scan
, TAP_IDLE
);
679 jtag_execute_queue();
680 alive_sleep(500); /* device needs at least 0.5s to self check */
683 scan
.in_value
= &blankreg
;
684 jtag_add_dr_scan(bank
->target
->tap
, 1, &scan
, TAP_IDLE
);
685 jtag_execute_queue();
689 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++)
690 bank
->sectors
[i
].is_erased
= sector_state(blankreg
, i
);
695 static int xcf_erase(struct flash_bank
*bank
, unsigned int first
,
698 if ((first
>= bank
->num_sectors
)
699 || (last
>= bank
->num_sectors
)
701 return ERROR_FLASH_SECTOR_INVALID
;
704 isc_clear_protect(bank
, first
, last
);
705 int ret
= isc_erase_sectors(bank
, first
, last
);
711 static int xcf_read(struct flash_bank
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
713 return read_write_data(bank
, NULL
, buffer
, false, offset
, count
);
716 static int xcf_write(struct flash_bank
*bank
, const uint8_t *buffer
, uint32_t offset
,
719 return read_write_data(bank
, buffer
, NULL
, true, offset
, count
);
722 static int xcf_protect(struct flash_bank
*bank
, int set
, unsigned int first
,
729 ret
= isc_set_protect(bank
, first
, last
);
731 /* write protection may be removed only with following erase */
732 isc_clear_protect(bank
, first
, last
);
733 ret
= isc_erase_sectors(bank
, first
, last
);
740 COMMAND_HANDLER(xcf_handle_ccb_command
) {
742 if (!((CMD_ARGC
== 1) || (CMD_ARGC
== 5)))
743 return ERROR_COMMAND_SYNTAX_ERROR
;
745 struct flash_bank
*bank
;
746 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
747 if (retval
!= ERROR_OK
)
750 uint16_t ccb
= 0xFFFF;
752 uint16_t old_ccb
= isc_read_ccb(bank
);
756 LOG_INFO("current CCB = 0x%X", old_ccb
);
759 /* skip over flash bank */
763 if (strcmp("external", CMD_ARGV
[0]) == 0)
765 else if (strcmp("internal", CMD_ARGV
[0]) == 0)
767 else if (strcmp("serial", CMD_ARGV
[0]) == 0)
769 else if (strcmp("parallel", CMD_ARGV
[0]) == 0)
771 else if (strcmp("slave", CMD_ARGV
[0]) == 0)
773 else if (strcmp("master", CMD_ARGV
[0]) == 0)
775 else if (strcmp("40", CMD_ARGV
[0]) == 0)
777 else if (strcmp("20", CMD_ARGV
[0]) == 0)
780 return ERROR_COMMAND_SYNTAX_ERROR
;
789 sector
= gucr_num(bank
);
790 isc_clear_protect(bank
, sector
, sector
);
791 int ret
= isc_erase_sectors(bank
, sector
, sector
);
794 ret
= isc_program_ccb(bank
, ccb
);
797 ret
= isc_program_single_revision_btc(bank
);
800 ret
= isc_set_data_done(bank
, sector
);
805 sector
= sucr_num(bank
);
806 isc_clear_protect(bank
, sector
, sector
);
807 ret
= isc_erase_sectors(bank
, sector
, sector
);
810 ret
= isc_program_singe_revision_sucr(bank
);
813 ret
= isc_set_data_done(bank
, sector
);
823 COMMAND_HANDLER(xcf_handle_configure_command
) {
826 return ERROR_COMMAND_SYNTAX_ERROR
;
828 struct flash_bank
*bank
;
829 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
830 if (retval
!= ERROR_OK
)
833 return fpga_configure(bank
);
836 static const struct command_registration xcf_exec_command_handlers
[] = {
839 .handler
= xcf_handle_configure_command
,
840 .mode
= COMMAND_EXEC
,
842 .help
= "Initiate FPGA loading procedure."
846 .handler
= xcf_handle_ccb_command
,
847 .mode
= COMMAND_EXEC
,
848 .usage
= "bank_id [('external'|'internal') "
849 "('serial'|'parallel') "
850 "('slave'|'master') "
852 .help
= "Write CCB register with supplied options and (silently) BTC "
853 "register with single revision options. Display current "
854 "CCB value when only bank_id supplied. "
855 "Following options available: "
856 "1) external or internal clock source; "
857 "2) serial or parallel bus mode; "
858 "3) slave or master mode; "
859 "4) clock frequency in MHz for internal clock in master mode;"
861 COMMAND_REGISTRATION_DONE
864 static const struct command_registration xcf_command_handlers
[] = {
868 .help
= "Xilinx platform flash command group",
870 .chain
= xcf_exec_command_handlers
872 COMMAND_REGISTRATION_DONE
875 const struct flash_driver xcf_flash
= {
878 .commands
= xcf_command_handlers
,
879 .flash_bank_command
= xcf_flash_bank_command
,
881 .protect
= xcf_protect
,
885 .auto_probe
= xcf_auto_probe
,
886 .erase_check
= xcf_erase_check
,
887 .protect_check
= xcf_protect_check
,
889 .free_driver_priv
= default_flash_free_driver_priv
,