1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 /***************************************************************************
4 * Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com> *
5 * Modified by Megan Wachs <megan@sifive.com> from the original stmsmi.c *
6 ***************************************************************************/
8 /* The Freedom E SPI controller is a SPI bus controller
9 * specifically designed for SPI Flash Memories on Freedom E platforms.
11 * Two working modes are available:
12 * - SW mode: the SPI is controlled by SW. Any custom commands can be sent
13 * on the bus. Writes are only possible in this mode.
14 * - HW mode: Memory content is directly
15 * accessible in CPU memory space. CPU can read and execute memory content.
19 * To have flash memory mapped in CPU memory space, the controller
20 * must have "HW mode" enabled.
21 * 1) The command "reset init" has to initialize the controller and put
22 * it in HW mode (this is actually the default out of reset for Freedom E systems).
23 * 2) every command in this file have to return to prompt in HW mode. */
31 #include <jtag/jtag.h>
32 #include <helper/time_support.h>
33 #include <target/algorithm.h>
34 #include "target/riscv/riscv.h"
36 /* Register offsets */
38 #define FESPI_REG_SCKDIV 0x00
39 #define FESPI_REG_SCKMODE 0x04
40 #define FESPI_REG_CSID 0x10
41 #define FESPI_REG_CSDEF 0x14
42 #define FESPI_REG_CSMODE 0x18
44 #define FESPI_REG_DCSSCK 0x28
45 #define FESPI_REG_DSCKCS 0x2a
46 #define FESPI_REG_DINTERCS 0x2c
47 #define FESPI_REG_DINTERXFR 0x2e
49 #define FESPI_REG_FMT 0x40
50 #define FESPI_REG_TXFIFO 0x48
51 #define FESPI_REG_RXFIFO 0x4c
52 #define FESPI_REG_TXCTRL 0x50
53 #define FESPI_REG_RXCTRL 0x54
55 #define FESPI_REG_FCTRL 0x60
56 #define FESPI_REG_FFMT 0x64
58 #define FESPI_REG_IE 0x70
59 #define FESPI_REG_IP 0x74
63 #define FESPI_SCK_POL 0x1
64 #define FESPI_SCK_PHA 0x2
66 #define FESPI_FMT_PROTO(x) ((x) & 0x3)
67 #define FESPI_FMT_ENDIAN(x) (((x) & 0x1) << 2)
68 #define FESPI_FMT_DIR(x) (((x) & 0x1) << 3)
69 #define FESPI_FMT_LEN(x) (((x) & 0xf) << 16)
72 #define FESPI_TXWM(x) ((x) & 0xffff)
74 #define FESPI_RXWM(x) ((x) & 0xffff)
76 #define FESPI_IP_TXWM 0x1
77 #define FESPI_IP_RXWM 0x2
79 #define FESPI_FCTRL_EN 0x1
81 #define FESPI_INSN_CMD_EN 0x1
82 #define FESPI_INSN_ADDR_LEN(x) (((x) & 0x7) << 1)
83 #define FESPI_INSN_PAD_CNT(x) (((x) & 0xf) << 4)
84 #define FESPI_INSN_CMD_PROTO(x) (((x) & 0x3) << 8)
85 #define FESPI_INSN_ADDR_PROTO(x) (((x) & 0x3) << 10)
86 #define FESPI_INSN_DATA_PROTO(x) (((x) & 0x3) << 12)
87 #define FESPI_INSN_CMD_CODE(x) (((x) & 0xff) << 16)
88 #define FESPI_INSN_PAD_CODE(x) (((x) & 0xff) << 24)
92 #define FESPI_CSMODE_AUTO 0
93 #define FESPI_CSMODE_HOLD 2
94 #define FESPI_CSMODE_OFF 3
96 #define FESPI_DIR_RX 0
97 #define FESPI_DIR_TX 1
99 #define FESPI_PROTO_S 0
100 #define FESPI_PROTO_D 1
101 #define FESPI_PROTO_Q 2
103 #define FESPI_ENDIAN_MSB 0
104 #define FESPI_ENDIAN_LSB 1
108 #define FESPI_CMD_TIMEOUT (100)
109 #define FESPI_PROBE_TIMEOUT (100)
110 #define FESPI_MAX_TIMEOUT (3000)
113 struct fespi_flash_bank {
115 target_addr_t ctrl_base;
116 const struct flash_device *dev;
119 struct fespi_target {
125 /* TODO !!! What is the right naming convention here? */
126 static const struct fespi_target target_devices[] = {
127 /* name, tap_idcode, ctrl_base */
128 { "Freedom E310-G000 SPI Flash", 0x10e31913, 0x10014000 },
129 { "Freedom E310-G002 SPI Flash", 0x20000913, 0x10014000 },
133 FLASH_BANK_COMMAND_HANDLER(fespi_flash_bank_command)
135 struct fespi_flash_bank *fespi_info;
137 LOG_DEBUG("%s", __func__);
140 return ERROR_COMMAND_SYNTAX_ERROR;
142 fespi_info = malloc(sizeof(struct fespi_flash_bank));
144 LOG_ERROR("not enough memory");
148 bank->driver_priv = fespi_info;
149 fespi_info->probed = false;
150 fespi_info->ctrl_base = 0;
152 COMMAND_PARSE_ADDRESS(CMD_ARGV[6], fespi_info->ctrl_base);
153 LOG_DEBUG("ASSUMING FESPI device at ctrl_base = " TARGET_ADDR_FMT,
154 fespi_info->ctrl_base);
160 static int fespi_read_reg(struct flash_bank *bank, uint32_t *value, target_addr_t address)
162 struct target *target = bank->target;
163 struct fespi_flash_bank *fespi_info = bank->driver_priv;
165 int result = target_read_u32(target, fespi_info->ctrl_base + address, value);
166 if (result != ERROR_OK) {
167 LOG_ERROR("fespi_read_reg() error at " TARGET_ADDR_FMT,
168 fespi_info->ctrl_base + address);
174 static int fespi_write_reg(struct flash_bank *bank, target_addr_t address, uint32_t value)
176 struct target *target = bank->target;
177 struct fespi_flash_bank *fespi_info = bank->driver_priv;
179 int result = target_write_u32(target, fespi_info->ctrl_base + address, value);
180 if (result != ERROR_OK) {
181 LOG_ERROR("fespi_write_reg() error writing 0x%" PRIx32 " to " TARGET_ADDR_FMT,
182 value, fespi_info->ctrl_base + address);
188 static int fespi_disable_hw_mode(struct flash_bank *bank)
191 if (fespi_read_reg(bank, &fctrl, FESPI_REG_FCTRL) != ERROR_OK)
193 return fespi_write_reg(bank, FESPI_REG_FCTRL, fctrl & ~FESPI_FCTRL_EN);
196 static int fespi_enable_hw_mode(struct flash_bank *bank)
199 if (fespi_read_reg(bank, &fctrl, FESPI_REG_FCTRL) != ERROR_OK)
201 return fespi_write_reg(bank, FESPI_REG_FCTRL, fctrl | FESPI_FCTRL_EN);
204 static int fespi_set_dir(struct flash_bank *bank, bool dir)
207 if (fespi_read_reg(bank, &fmt, FESPI_REG_FMT) != ERROR_OK)
210 return fespi_write_reg(bank, FESPI_REG_FMT,
211 (fmt & ~(FESPI_FMT_DIR(0xFFFFFFFF))) | FESPI_FMT_DIR(dir));
214 static int fespi_txwm_wait(struct flash_bank *bank)
216 int64_t start = timeval_ms();
220 if (fespi_read_reg(bank, &ip, FESPI_REG_IP) != ERROR_OK)
222 if (ip & FESPI_IP_TXWM)
224 int64_t now = timeval_ms();
225 if (now - start > 1000) {
226 LOG_ERROR("ip.txwm didn't get set.");
227 return ERROR_TARGET_TIMEOUT;
234 static int fespi_tx(struct flash_bank *bank, uint8_t in)
236 int64_t start = timeval_ms();
240 if (fespi_read_reg(bank, &txfifo, FESPI_REG_TXFIFO) != ERROR_OK)
244 int64_t now = timeval_ms();
245 if (now - start > 1000) {
246 LOG_ERROR("txfifo stayed negative.");
247 return ERROR_TARGET_TIMEOUT;
251 return fespi_write_reg(bank, FESPI_REG_TXFIFO, in);
254 static int fespi_rx(struct flash_bank *bank, uint8_t *out)
256 int64_t start = timeval_ms();
260 if (fespi_read_reg(bank, &value, FESPI_REG_RXFIFO) != ERROR_OK)
264 int64_t now = timeval_ms();
265 if (now - start > 1000) {
266 LOG_ERROR("rxfifo didn't go positive (value=0x%" PRIx32 ").", value);
267 return ERROR_TARGET_TIMEOUT;
277 /* TODO!!! Why don't we need to call this after writing? */
278 static int fespi_wip(struct flash_bank *bank, int timeout)
282 fespi_set_dir(bank, FESPI_DIR_RX);
284 if (fespi_write_reg(bank, FESPI_REG_CSMODE, FESPI_CSMODE_HOLD) != ERROR_OK)
286 endtime = timeval_ms() + timeout;
288 fespi_tx(bank, SPIFLASH_READ_STATUS);
289 if (fespi_rx(bank, NULL) != ERROR_OK)
297 if (fespi_rx(bank, &rx) != ERROR_OK)
299 if ((rx & SPIFLASH_BSY_BIT) == 0) {
300 if (fespi_write_reg(bank, FESPI_REG_CSMODE, FESPI_CSMODE_AUTO) != ERROR_OK)
302 fespi_set_dir(bank, FESPI_DIR_TX);
305 } while (timeval_ms() < endtime);
307 LOG_ERROR("timeout");
311 static int fespi_erase_sector(struct flash_bank *bank, int sector)
313 struct fespi_flash_bank *fespi_info = bank->driver_priv;
316 retval = fespi_tx(bank, SPIFLASH_WRITE_ENABLE);
317 if (retval != ERROR_OK)
319 retval = fespi_txwm_wait(bank);
320 if (retval != ERROR_OK)
323 if (fespi_write_reg(bank, FESPI_REG_CSMODE, FESPI_CSMODE_HOLD) != ERROR_OK)
325 retval = fespi_tx(bank, fespi_info->dev->erase_cmd);
326 if (retval != ERROR_OK)
328 sector = bank->sectors[sector].offset;
329 if (bank->size > 0x1000000) {
330 retval = fespi_tx(bank, sector >> 24);
331 if (retval != ERROR_OK)
334 retval = fespi_tx(bank, sector >> 16);
335 if (retval != ERROR_OK)
337 retval = fespi_tx(bank, sector >> 8);
338 if (retval != ERROR_OK)
340 retval = fespi_tx(bank, sector);
341 if (retval != ERROR_OK)
343 retval = fespi_txwm_wait(bank);
344 if (retval != ERROR_OK)
346 if (fespi_write_reg(bank, FESPI_REG_CSMODE, FESPI_CSMODE_AUTO) != ERROR_OK)
349 retval = fespi_wip(bank, FESPI_MAX_TIMEOUT);
350 if (retval != ERROR_OK)
356 static int fespi_erase(struct flash_bank *bank, unsigned int first,
359 struct target *target = bank->target;
360 struct fespi_flash_bank *fespi_info = bank->driver_priv;
361 int retval = ERROR_OK;
363 LOG_DEBUG("%s: from sector %u to sector %u", __func__, first, last);
365 if (target->state != TARGET_HALTED) {
366 LOG_ERROR("Target not halted");
367 return ERROR_TARGET_NOT_HALTED;
370 if ((last < first) || (last >= bank->num_sectors)) {
371 LOG_ERROR("Flash sector invalid");
372 return ERROR_FLASH_SECTOR_INVALID;
375 if (!(fespi_info->probed)) {
376 LOG_ERROR("Flash bank not probed");
377 return ERROR_FLASH_BANK_NOT_PROBED;
380 for (unsigned int sector = first; sector <= last; sector++) {
381 if (bank->sectors[sector].is_protected) {
382 LOG_ERROR("Flash sector %u protected", sector);
387 if (fespi_info->dev->erase_cmd == 0x00)
388 return ERROR_FLASH_OPER_UNSUPPORTED;
390 if (fespi_write_reg(bank, FESPI_REG_TXCTRL, FESPI_TXWM(1)) != ERROR_OK)
392 retval = fespi_txwm_wait(bank);
393 if (retval != ERROR_OK) {
394 LOG_ERROR("WM Didn't go high before attempting.");
398 /* Disable Hardware accesses*/
399 if (fespi_disable_hw_mode(bank) != ERROR_OK)
403 retval = fespi_wip(bank, FESPI_PROBE_TIMEOUT);
404 if (retval != ERROR_OK)
407 for (unsigned int sector = first; sector <= last; sector++) {
408 retval = fespi_erase_sector(bank, sector);
409 if (retval != ERROR_OK)
414 /* Switch to HW mode before return to prompt */
416 if (fespi_enable_hw_mode(bank) != ERROR_OK)
421 static int fespi_protect(struct flash_bank *bank, int set,
422 unsigned int first, unsigned int last)
424 for (unsigned int sector = first; sector <= last; sector++)
425 bank->sectors[sector].is_protected = set;
429 static int slow_fespi_write_buffer(struct flash_bank *bank,
430 const uint8_t *buffer, uint32_t offset, uint32_t len)
432 struct fespi_flash_bank *fespi_info = bank->driver_priv;
435 /* TODO!!! assert that len < page size */
437 if (fespi_tx(bank, SPIFLASH_WRITE_ENABLE) != ERROR_OK)
439 if (fespi_txwm_wait(bank) != ERROR_OK)
442 if (fespi_write_reg(bank, FESPI_REG_CSMODE, FESPI_CSMODE_HOLD) != ERROR_OK)
445 if (fespi_tx(bank, fespi_info->dev->pprog_cmd) != ERROR_OK)
448 if (bank->size > 0x1000000 && fespi_tx(bank, offset >> 24) != ERROR_OK)
450 if (fespi_tx(bank, offset >> 16) != ERROR_OK)
452 if (fespi_tx(bank, offset >> 8) != ERROR_OK)
454 if (fespi_tx(bank, offset) != ERROR_OK)
457 for (ii = 0; ii < len; ii++) {
458 if (fespi_tx(bank, buffer[ii]) != ERROR_OK)
462 if (fespi_txwm_wait(bank) != ERROR_OK)
465 if (fespi_write_reg(bank, FESPI_REG_CSMODE, FESPI_CSMODE_AUTO) != ERROR_OK)
473 static const uint8_t riscv32_bin[] = {
474 #include "../../../contrib/loaders/flash/fespi/riscv32_fespi.inc"
477 static const uint8_t riscv64_bin[] = {
478 #include "../../../contrib/loaders/flash/fespi/riscv64_fespi.inc"
481 static int fespi_write(struct flash_bank *bank, const uint8_t *buffer,
482 uint32_t offset, uint32_t count)
484 struct target *target = bank->target;
485 struct fespi_flash_bank *fespi_info = bank->driver_priv;
486 uint32_t cur_count, page_size;
487 int retval = ERROR_OK;
489 LOG_DEBUG("bank->size=0x%x offset=0x%08" PRIx32 " count=0x%08" PRIx32,
490 bank->size, offset, count);
492 if (target->state != TARGET_HALTED) {
493 LOG_ERROR("Target not halted");
494 return ERROR_TARGET_NOT_HALTED;
497 if (offset + count > fespi_info->dev->size_in_bytes) {
498 LOG_WARNING("Write past end of flash. Extra data discarded.");
499 count = fespi_info->dev->size_in_bytes - offset;
502 /* Check sector protection */
503 for (unsigned int sector = 0; sector < bank->num_sectors; sector++) {
504 /* Start offset in or before this sector? */
505 /* End offset in or behind this sector? */
507 (bank->sectors[sector].offset + bank->sectors[sector].size))
508 && ((offset + count - 1) >= bank->sectors[sector].offset)
509 && bank->sectors[sector].is_protected) {
510 LOG_ERROR("Flash sector %u protected", sector);
515 unsigned int xlen = riscv_xlen(target);
516 struct working_area *algorithm_wa = NULL;
517 struct working_area *data_wa = NULL;
522 bin_size = sizeof(riscv32_bin);
525 bin_size = sizeof(riscv64_bin);
528 unsigned data_wa_size = 0;
529 if (target_alloc_working_area(target, bin_size, &algorithm_wa) == ERROR_OK) {
530 retval = target_write_buffer(target, algorithm_wa->address,
532 if (retval != ERROR_OK) {
533 LOG_ERROR("Failed to write code to " TARGET_ADDR_FMT ": %d",
534 algorithm_wa->address, retval);
535 target_free_working_area(target, algorithm_wa);
539 data_wa_size = MIN(target_get_working_area_avail(target), count);
540 if (data_wa_size < 128) {
541 LOG_WARNING("Couldn't allocate data working area.");
542 target_free_working_area(target, algorithm_wa);
544 } else if (target_alloc_working_area(target, data_wa_size, &data_wa) != ERROR_OK) {
545 target_free_working_area(target, algorithm_wa);
550 LOG_WARNING("Couldn't allocate %zd-byte working area.", bin_size);
554 /* If no valid page_size, use reasonable default. */
555 page_size = fespi_info->dev->pagesize ?
556 fespi_info->dev->pagesize : SPIFLASH_DEF_PAGESIZE;
559 struct reg_param reg_params[6];
560 init_reg_param(®_params[0], "a0", xlen, PARAM_IN_OUT);
561 init_reg_param(®_params[1], "a1", xlen, PARAM_OUT);
562 init_reg_param(®_params[2], "a2", xlen, PARAM_OUT);
563 init_reg_param(®_params[3], "a3", xlen, PARAM_OUT);
564 init_reg_param(®_params[4], "a4", xlen, PARAM_OUT);
565 init_reg_param(®_params[5], "a5", xlen, PARAM_OUT);
568 cur_count = MIN(count, data_wa_size);
569 buf_set_u64(reg_params[0].value, 0, xlen, fespi_info->ctrl_base);
570 buf_set_u64(reg_params[1].value, 0, xlen, page_size);
571 buf_set_u64(reg_params[2].value, 0, xlen, data_wa->address);
572 buf_set_u64(reg_params[3].value, 0, xlen, offset);
573 buf_set_u64(reg_params[4].value, 0, xlen, cur_count);
574 buf_set_u64(reg_params[5].value, 0, xlen,
575 fespi_info->dev->pprog_cmd | (bank->size > 0x1000000 ? 0x100 : 0));
577 retval = target_write_buffer(target, data_wa->address, cur_count,
579 if (retval != ERROR_OK) {
580 LOG_DEBUG("Failed to write %d bytes to " TARGET_ADDR_FMT ": %d",
581 cur_count, data_wa->address, retval);
585 LOG_DEBUG("write(ctrl_base=0x%" TARGET_PRIxADDR ", page_size=0x%x, "
586 "address=0x%" TARGET_PRIxADDR ", offset=0x%" PRIx32
587 ", count=0x%" PRIx32 "), buffer=%02x %02x %02x %02x %02x %02x ..." PRIx32,
588 fespi_info->ctrl_base, page_size, data_wa->address, offset, cur_count,
589 buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]);
590 retval = target_run_algorithm(target, 0, NULL,
591 ARRAY_SIZE(reg_params), reg_params,
592 algorithm_wa->address, 0, cur_count * 2, NULL);
593 if (retval != ERROR_OK) {
594 LOG_ERROR("Failed to execute algorithm at " TARGET_ADDR_FMT ": %d",
595 algorithm_wa->address, retval);
599 uint64_t algorithm_result = buf_get_u64(reg_params[0].value, 0, xlen);
600 if (algorithm_result != 0) {
601 LOG_ERROR("Algorithm returned error %" PRId64, algorithm_result);
611 target_free_working_area(target, data_wa);
612 target_free_working_area(target, algorithm_wa);
615 fespi_txwm_wait(bank);
617 /* Disable Hardware accesses*/
618 if (fespi_disable_hw_mode(bank) != ERROR_OK)
622 retval = fespi_wip(bank, FESPI_PROBE_TIMEOUT);
623 if (retval != ERROR_OK)
626 uint32_t page_offset = offset % page_size;
627 /* central part, aligned words */
629 /* clip block at page boundary */
630 if (page_offset + count > page_size)
631 cur_count = page_size - page_offset;
635 retval = slow_fespi_write_buffer(bank, buffer, offset, cur_count);
636 if (retval != ERROR_OK)
645 /* Switch to HW mode before return to prompt */
646 if (fespi_enable_hw_mode(bank) != ERROR_OK)
653 target_free_working_area(target, data_wa);
654 target_free_working_area(target, algorithm_wa);
656 /* Switch to HW mode before return to prompt */
657 if (fespi_enable_hw_mode(bank) != ERROR_OK)
663 /* Return ID of flash device */
664 /* On exit, SW mode is kept */
665 static int fespi_read_flash_id(struct flash_bank *bank, uint32_t *id)
667 struct target *target = bank->target;
670 if (target->state != TARGET_HALTED) {
671 LOG_ERROR("Target not halted");
672 return ERROR_TARGET_NOT_HALTED;
675 fespi_txwm_wait(bank);
678 retval = fespi_wip(bank, FESPI_PROBE_TIMEOUT);
679 if (retval != ERROR_OK)
682 fespi_set_dir(bank, FESPI_DIR_RX);
684 /* Send SPI command "read ID" */
685 if (fespi_write_reg(bank, FESPI_REG_CSMODE, FESPI_CSMODE_HOLD) != ERROR_OK)
688 fespi_tx(bank, SPIFLASH_READ_ID);
689 /* Send dummy bytes to actually read the ID.*/
694 /* read ID from Receive Register */
696 if (fespi_rx(bank, NULL) != ERROR_OK)
699 if (fespi_rx(bank, &rx) != ERROR_OK)
702 if (fespi_rx(bank, &rx) != ERROR_OK)
705 if (fespi_rx(bank, &rx) != ERROR_OK)
709 if (fespi_write_reg(bank, FESPI_REG_CSMODE, FESPI_CSMODE_AUTO) != ERROR_OK)
712 fespi_set_dir(bank, FESPI_DIR_TX);
717 static int fespi_probe(struct flash_bank *bank)
719 struct target *target = bank->target;
720 struct fespi_flash_bank *fespi_info = bank->driver_priv;
721 struct flash_sector *sectors;
722 uint32_t id = 0; /* silence uninitialized warning */
723 const struct fespi_target *target_device;
727 if (fespi_info->probed)
729 fespi_info->probed = false;
731 if (fespi_info->ctrl_base == 0) {
732 for (target_device = target_devices ; target_device->name ; ++target_device)
733 if (target_device->tap_idcode == target->tap->idcode)
736 if (!target_device->name) {
737 LOG_ERROR("Device ID 0x%" PRIx32 " is not known as FESPI capable",
738 target->tap->idcode);
742 fespi_info->ctrl_base = target_device->ctrl_base;
744 LOG_DEBUG("Valid FESPI on device %s at address " TARGET_ADDR_FMT,
745 target_device->name, bank->base);
748 LOG_DEBUG("Assuming FESPI as specified at address " TARGET_ADDR_FMT
749 " with ctrl at " TARGET_ADDR_FMT, fespi_info->ctrl_base,
753 /* read and decode flash ID; returns in SW mode */
754 if (fespi_write_reg(bank, FESPI_REG_TXCTRL, FESPI_TXWM(1)) != ERROR_OK)
756 fespi_set_dir(bank, FESPI_DIR_TX);
758 /* Disable Hardware accesses*/
759 if (fespi_disable_hw_mode(bank) != ERROR_OK)
762 retval = fespi_read_flash_id(bank, &id);
764 if (fespi_enable_hw_mode(bank) != ERROR_OK)
766 if (retval != ERROR_OK)
769 fespi_info->dev = NULL;
770 for (const struct flash_device *p = flash_devices; p->name ; p++)
771 if (p->device_id == id) {
776 if (!fespi_info->dev) {
777 LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32 ")", id);
781 LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32 ")",
782 fespi_info->dev->name, fespi_info->dev->device_id);
784 /* Set correct size value */
785 bank->size = fespi_info->dev->size_in_bytes;
787 if (bank->size <= (1UL << 16))
788 LOG_WARNING("device needs 2-byte addresses - not implemented");
790 /* if no sectors, treat whole bank as single sector */
791 sectorsize = fespi_info->dev->sectorsize ?
792 fespi_info->dev->sectorsize : fespi_info->dev->size_in_bytes;
794 /* create and fill sectors array */
795 bank->num_sectors = fespi_info->dev->size_in_bytes / sectorsize;
796 sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
798 LOG_ERROR("not enough memory");
802 for (unsigned int sector = 0; sector < bank->num_sectors; sector++) {
803 sectors[sector].offset = sector * sectorsize;
804 sectors[sector].size = sectorsize;
805 sectors[sector].is_erased = -1;
806 sectors[sector].is_protected = 0;
809 bank->sectors = sectors;
810 fespi_info->probed = true;
814 static int fespi_auto_probe(struct flash_bank *bank)
816 struct fespi_flash_bank *fespi_info = bank->driver_priv;
817 if (fespi_info->probed)
819 return fespi_probe(bank);
822 static int fespi_protect_check(struct flash_bank *bank)
824 /* Nothing to do. Protection is only handled in SW. */
828 static int get_fespi_info(struct flash_bank *bank, struct command_invocation *cmd)
830 struct fespi_flash_bank *fespi_info = bank->driver_priv;
832 if (!(fespi_info->probed)) {
833 command_print_sameline(cmd, "\nFESPI flash bank not probed yet\n");
837 command_print_sameline(cmd, "\nFESPI flash information:\n"
838 " Device \'%s\' (ID 0x%08" PRIx32 ")\n",
839 fespi_info->dev->name, fespi_info->dev->device_id);
844 const struct flash_driver fespi_flash = {
846 .flash_bank_command = fespi_flash_bank_command,
847 .erase = fespi_erase,
848 .protect = fespi_protect,
849 .write = fespi_write,
850 .read = default_flash_read,
851 .probe = fespi_probe,
852 .auto_probe = fespi_auto_probe,
853 .erase_check = default_flash_blank_check,
854 .protect_check = fespi_protect_check,
855 .info = get_fespi_info,
856 .free_driver_priv = default_flash_free_driver_priv