1 /***************************************************************************
2 * Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com> *
3 * Modified by Megan Wachs <megan@sifive.com> from the original stmsmi.c *
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 ***************************************************************************/
19 /* The Freedom E SPI controller is a SPI bus controller
20 * specifically designed for SPI Flash Memories on Freedom E platforms.
22 * Two working modes are available:
23 * - SW mode: the SPI is controlled by SW. Any custom commands can be sent
24 * on the bus. Writes are only possible in this mode.
25 * - HW mode: Memory content is directly
26 * accessible in CPU memory space. CPU can read and execute memory content.
30 * To have flash memory mapped in CPU memory space, the controller
31 * must have "HW mode" enabled.
32 * 1) The command "reset init" has to initialize the controller and put
33 * it in HW mode (this is actually the default out of reset for Freedom E systems).
34 * 2) every command in this file have to return to prompt in HW mode. */
42 #include <jtag/jtag.h>
43 #include <helper/time_support.h>
44 #include <target/algorithm.h>
45 #include "target/riscv/riscv.h"
47 /* Register offsets */
49 #define FESPI_REG_SCKDIV 0x00
50 #define FESPI_REG_SCKMODE 0x04
51 #define FESPI_REG_CSID 0x10
52 #define FESPI_REG_CSDEF 0x14
53 #define FESPI_REG_CSMODE 0x18
55 #define FESPI_REG_DCSSCK 0x28
56 #define FESPI_REG_DSCKCS 0x2a
57 #define FESPI_REG_DINTERCS 0x2c
58 #define FESPI_REG_DINTERXFR 0x2e
60 #define FESPI_REG_FMT 0x40
61 #define FESPI_REG_TXFIFO 0x48
62 #define FESPI_REG_RXFIFO 0x4c
63 #define FESPI_REG_TXCTRL 0x50
64 #define FESPI_REG_RXCTRL 0x54
66 #define FESPI_REG_FCTRL 0x60
67 #define FESPI_REG_FFMT 0x64
69 #define FESPI_REG_IE 0x70
70 #define FESPI_REG_IP 0x74
74 #define FESPI_SCK_POL 0x1
75 #define FESPI_SCK_PHA 0x2
77 #define FESPI_FMT_PROTO(x) ((x) & 0x3)
78 #define FESPI_FMT_ENDIAN(x) (((x) & 0x1) << 2)
79 #define FESPI_FMT_DIR(x) (((x) & 0x1) << 3)
80 #define FESPI_FMT_LEN(x) (((x) & 0xf) << 16)
83 #define FESPI_TXWM(x) ((x) & 0xffff)
85 #define FESPI_RXWM(x) ((x) & 0xffff)
87 #define FESPI_IP_TXWM 0x1
88 #define FESPI_IP_RXWM 0x2
90 #define FESPI_FCTRL_EN 0x1
92 #define FESPI_INSN_CMD_EN 0x1
93 #define FESPI_INSN_ADDR_LEN(x) (((x) & 0x7) << 1)
94 #define FESPI_INSN_PAD_CNT(x) (((x) & 0xf) << 4)
95 #define FESPI_INSN_CMD_PROTO(x) (((x) & 0x3) << 8)
96 #define FESPI_INSN_ADDR_PROTO(x) (((x) & 0x3) << 10)
97 #define FESPI_INSN_DATA_PROTO(x) (((x) & 0x3) << 12)
98 #define FESPI_INSN_CMD_CODE(x) (((x) & 0xff) << 16)
99 #define FESPI_INSN_PAD_CODE(x) (((x) & 0xff) << 24)
103 #define FESPI_CSMODE_AUTO 0
104 #define FESPI_CSMODE_HOLD 2
105 #define FESPI_CSMODE_OFF 3
107 #define FESPI_DIR_RX 0
108 #define FESPI_DIR_TX 1
110 #define FESPI_PROTO_S 0
111 #define FESPI_PROTO_D 1
112 #define FESPI_PROTO_Q 2
114 #define FESPI_ENDIAN_MSB 0
115 #define FESPI_ENDIAN_LSB 1
119 #define FESPI_CMD_TIMEOUT (100)
120 #define FESPI_PROBE_TIMEOUT (100)
121 #define FESPI_MAX_TIMEOUT (3000)
124 struct fespi_flash_bank {
126 target_addr_t ctrl_base;
127 const struct flash_device *dev;
130 struct fespi_target {
136 /* TODO !!! What is the right naming convention here? */
137 static const struct fespi_target target_devices[] = {
138 /* name, tap_idcode, ctrl_base */
139 { "Freedom E310-G000 SPI Flash", 0x10e31913, 0x10014000 },
140 { "Freedom E310-G002 SPI Flash", 0x20000913, 0x10014000 },
144 FLASH_BANK_COMMAND_HANDLER(fespi_flash_bank_command)
146 struct fespi_flash_bank *fespi_info;
148 LOG_DEBUG("%s", __func__);
151 return ERROR_COMMAND_SYNTAX_ERROR;
153 fespi_info = malloc(sizeof(struct fespi_flash_bank));
155 LOG_ERROR("not enough memory");
159 bank->driver_priv = fespi_info;
160 fespi_info->probed = false;
161 fespi_info->ctrl_base = 0;
163 COMMAND_PARSE_ADDRESS(CMD_ARGV[6], fespi_info->ctrl_base);
164 LOG_DEBUG("ASSUMING FESPI device at ctrl_base = " TARGET_ADDR_FMT,
165 fespi_info->ctrl_base);
171 static int fespi_read_reg(struct flash_bank *bank, uint32_t *value, target_addr_t address)
173 struct target *target = bank->target;
174 struct fespi_flash_bank *fespi_info = bank->driver_priv;
176 int result = target_read_u32(target, fespi_info->ctrl_base + address, value);
177 if (result != ERROR_OK) {
178 LOG_ERROR("fespi_read_reg() error at " TARGET_ADDR_FMT,
179 fespi_info->ctrl_base + address);
185 static int fespi_write_reg(struct flash_bank *bank, target_addr_t address, uint32_t value)
187 struct target *target = bank->target;
188 struct fespi_flash_bank *fespi_info = bank->driver_priv;
190 int result = target_write_u32(target, fespi_info->ctrl_base + address, value);
191 if (result != ERROR_OK) {
192 LOG_ERROR("fespi_write_reg() error writing 0x%" PRIx32 " to " TARGET_ADDR_FMT,
193 value, fespi_info->ctrl_base + address);
199 static int fespi_disable_hw_mode(struct flash_bank *bank)
202 if (fespi_read_reg(bank, &fctrl, FESPI_REG_FCTRL) != ERROR_OK)
204 return fespi_write_reg(bank, FESPI_REG_FCTRL, fctrl & ~FESPI_FCTRL_EN);
207 static int fespi_enable_hw_mode(struct flash_bank *bank)
210 if (fespi_read_reg(bank, &fctrl, FESPI_REG_FCTRL) != ERROR_OK)
212 return fespi_write_reg(bank, FESPI_REG_FCTRL, fctrl | FESPI_FCTRL_EN);
215 static int fespi_set_dir(struct flash_bank *bank, bool dir)
218 if (fespi_read_reg(bank, &fmt, FESPI_REG_FMT) != ERROR_OK)
221 return fespi_write_reg(bank, FESPI_REG_FMT,
222 (fmt & ~(FESPI_FMT_DIR(0xFFFFFFFF))) | FESPI_FMT_DIR(dir));
225 static int fespi_txwm_wait(struct flash_bank *bank)
227 int64_t start = timeval_ms();
231 if (fespi_read_reg(bank, &ip, FESPI_REG_IP) != ERROR_OK)
233 if (ip & FESPI_IP_TXWM)
235 int64_t now = timeval_ms();
236 if (now - start > 1000) {
237 LOG_ERROR("ip.txwm didn't get set.");
238 return ERROR_TARGET_TIMEOUT;
245 static int fespi_tx(struct flash_bank *bank, uint8_t in)
247 int64_t start = timeval_ms();
251 if (fespi_read_reg(bank, &txfifo, FESPI_REG_TXFIFO) != ERROR_OK)
255 int64_t now = timeval_ms();
256 if (now - start > 1000) {
257 LOG_ERROR("txfifo stayed negative.");
258 return ERROR_TARGET_TIMEOUT;
262 return fespi_write_reg(bank, FESPI_REG_TXFIFO, in);
265 static int fespi_rx(struct flash_bank *bank, uint8_t *out)
267 int64_t start = timeval_ms();
271 if (fespi_read_reg(bank, &value, FESPI_REG_RXFIFO) != ERROR_OK)
275 int64_t now = timeval_ms();
276 if (now - start > 1000) {
277 LOG_ERROR("rxfifo didn't go positive (value=0x%" PRIx32 ").", value);
278 return ERROR_TARGET_TIMEOUT;
288 /* TODO!!! Why don't we need to call this after writing? */
289 static int fespi_wip(struct flash_bank *bank, int timeout)
293 fespi_set_dir(bank, FESPI_DIR_RX);
295 if (fespi_write_reg(bank, FESPI_REG_CSMODE, FESPI_CSMODE_HOLD) != ERROR_OK)
297 endtime = timeval_ms() + timeout;
299 fespi_tx(bank, SPIFLASH_READ_STATUS);
300 if (fespi_rx(bank, NULL) != ERROR_OK)
308 if (fespi_rx(bank, &rx) != ERROR_OK)
310 if ((rx & SPIFLASH_BSY_BIT) == 0) {
311 if (fespi_write_reg(bank, FESPI_REG_CSMODE, FESPI_CSMODE_AUTO) != ERROR_OK)
313 fespi_set_dir(bank, FESPI_DIR_TX);
316 } while (timeval_ms() < endtime);
318 LOG_ERROR("timeout");
322 static int fespi_erase_sector(struct flash_bank *bank, int sector)
324 struct fespi_flash_bank *fespi_info = bank->driver_priv;
327 retval = fespi_tx(bank, SPIFLASH_WRITE_ENABLE);
328 if (retval != ERROR_OK)
330 retval = fespi_txwm_wait(bank);
331 if (retval != ERROR_OK)
334 if (fespi_write_reg(bank, FESPI_REG_CSMODE, FESPI_CSMODE_HOLD) != ERROR_OK)
336 retval = fespi_tx(bank, fespi_info->dev->erase_cmd);
337 if (retval != ERROR_OK)
339 sector = bank->sectors[sector].offset;
340 if (bank->size > 0x1000000) {
341 retval = fespi_tx(bank, sector >> 24);
342 if (retval != ERROR_OK)
345 retval = fespi_tx(bank, sector >> 16);
346 if (retval != ERROR_OK)
348 retval = fespi_tx(bank, sector >> 8);
349 if (retval != ERROR_OK)
351 retval = fespi_tx(bank, sector);
352 if (retval != ERROR_OK)
354 retval = fespi_txwm_wait(bank);
355 if (retval != ERROR_OK)
357 if (fespi_write_reg(bank, FESPI_REG_CSMODE, FESPI_CSMODE_AUTO) != ERROR_OK)
360 retval = fespi_wip(bank, FESPI_MAX_TIMEOUT);
361 if (retval != ERROR_OK)
367 static int fespi_erase(struct flash_bank *bank, unsigned int first,
370 struct target *target = bank->target;
371 struct fespi_flash_bank *fespi_info = bank->driver_priv;
372 int retval = ERROR_OK;
374 LOG_DEBUG("%s: from sector %u to sector %u", __func__, first, last);
376 if (target->state != TARGET_HALTED) {
377 LOG_ERROR("Target not halted");
378 return ERROR_TARGET_NOT_HALTED;
381 if ((last < first) || (last >= bank->num_sectors)) {
382 LOG_ERROR("Flash sector invalid");
383 return ERROR_FLASH_SECTOR_INVALID;
386 if (!(fespi_info->probed)) {
387 LOG_ERROR("Flash bank not probed");
388 return ERROR_FLASH_BANK_NOT_PROBED;
391 for (unsigned int sector = first; sector <= last; sector++) {
392 if (bank->sectors[sector].is_protected) {
393 LOG_ERROR("Flash sector %u protected", sector);
398 if (fespi_info->dev->erase_cmd == 0x00)
399 return ERROR_FLASH_OPER_UNSUPPORTED;
401 if (fespi_write_reg(bank, FESPI_REG_TXCTRL, FESPI_TXWM(1)) != ERROR_OK)
403 retval = fespi_txwm_wait(bank);
404 if (retval != ERROR_OK) {
405 LOG_ERROR("WM Didn't go high before attempting.");
409 /* Disable Hardware accesses*/
410 if (fespi_disable_hw_mode(bank) != ERROR_OK)
414 retval = fespi_wip(bank, FESPI_PROBE_TIMEOUT);
415 if (retval != ERROR_OK)
418 for (unsigned int sector = first; sector <= last; sector++) {
419 retval = fespi_erase_sector(bank, sector);
420 if (retval != ERROR_OK)
425 /* Switch to HW mode before return to prompt */
427 if (fespi_enable_hw_mode(bank) != ERROR_OK)
432 static int fespi_protect(struct flash_bank *bank, int set,
433 unsigned int first, unsigned int last)
435 for (unsigned int sector = first; sector <= last; sector++)
436 bank->sectors[sector].is_protected = set;
440 static int slow_fespi_write_buffer(struct flash_bank *bank,
441 const uint8_t *buffer, uint32_t offset, uint32_t len)
443 struct fespi_flash_bank *fespi_info = bank->driver_priv;
446 /* TODO!!! assert that len < page size */
448 if (fespi_tx(bank, SPIFLASH_WRITE_ENABLE) != ERROR_OK)
450 if (fespi_txwm_wait(bank) != ERROR_OK)
453 if (fespi_write_reg(bank, FESPI_REG_CSMODE, FESPI_CSMODE_HOLD) != ERROR_OK)
456 if (fespi_tx(bank, fespi_info->dev->pprog_cmd) != ERROR_OK)
459 if (bank->size > 0x1000000 && fespi_tx(bank, offset >> 24) != ERROR_OK)
461 if (fespi_tx(bank, offset >> 16) != ERROR_OK)
463 if (fespi_tx(bank, offset >> 8) != ERROR_OK)
465 if (fespi_tx(bank, offset) != ERROR_OK)
468 for (ii = 0; ii < len; ii++) {
469 if (fespi_tx(bank, buffer[ii]) != ERROR_OK)
473 if (fespi_txwm_wait(bank) != ERROR_OK)
476 if (fespi_write_reg(bank, FESPI_REG_CSMODE, FESPI_CSMODE_AUTO) != ERROR_OK)
484 static const uint8_t riscv32_bin[] = {
485 #include "../../../contrib/loaders/flash/fespi/riscv32_fespi.inc"
488 static const uint8_t riscv64_bin[] = {
489 #include "../../../contrib/loaders/flash/fespi/riscv64_fespi.inc"
492 static int fespi_write(struct flash_bank *bank, const uint8_t *buffer,
493 uint32_t offset, uint32_t count)
495 struct target *target = bank->target;
496 struct fespi_flash_bank *fespi_info = bank->driver_priv;
497 uint32_t cur_count, page_size;
498 int retval = ERROR_OK;
500 LOG_DEBUG("bank->size=0x%x offset=0x%08" PRIx32 " count=0x%08" PRIx32,
501 bank->size, offset, count);
503 if (target->state != TARGET_HALTED) {
504 LOG_ERROR("Target not halted");
505 return ERROR_TARGET_NOT_HALTED;
508 if (offset + count > fespi_info->dev->size_in_bytes) {
509 LOG_WARNING("Write past end of flash. Extra data discarded.");
510 count = fespi_info->dev->size_in_bytes - offset;
513 /* Check sector protection */
514 for (unsigned int sector = 0; sector < bank->num_sectors; sector++) {
515 /* Start offset in or before this sector? */
516 /* End offset in or behind this sector? */
518 (bank->sectors[sector].offset + bank->sectors[sector].size))
519 && ((offset + count - 1) >= bank->sectors[sector].offset)
520 && bank->sectors[sector].is_protected) {
521 LOG_ERROR("Flash sector %u protected", sector);
526 unsigned int xlen = riscv_xlen(target);
527 struct working_area *algorithm_wa = NULL;
528 struct working_area *data_wa = NULL;
533 bin_size = sizeof(riscv32_bin);
536 bin_size = sizeof(riscv64_bin);
539 unsigned data_wa_size = 0;
540 if (target_alloc_working_area(target, bin_size, &algorithm_wa) == ERROR_OK) {
541 retval = target_write_buffer(target, algorithm_wa->address,
543 if (retval != ERROR_OK) {
544 LOG_ERROR("Failed to write code to " TARGET_ADDR_FMT ": %d",
545 algorithm_wa->address, retval);
546 target_free_working_area(target, algorithm_wa);
550 data_wa_size = MIN(target_get_working_area_avail(target), count);
551 if (data_wa_size < 128) {
552 LOG_WARNING("Couldn't allocate data working area.");
553 target_free_working_area(target, algorithm_wa);
555 } else if (target_alloc_working_area(target, data_wa_size, &data_wa) != ERROR_OK) {
556 target_free_working_area(target, algorithm_wa);
561 LOG_WARNING("Couldn't allocate %zd-byte working area.", bin_size);
565 /* If no valid page_size, use reasonable default. */
566 page_size = fespi_info->dev->pagesize ?
567 fespi_info->dev->pagesize : SPIFLASH_DEF_PAGESIZE;
570 struct reg_param reg_params[6];
571 init_reg_param(®_params[0], "a0", xlen, PARAM_IN_OUT);
572 init_reg_param(®_params[1], "a1", xlen, PARAM_OUT);
573 init_reg_param(®_params[2], "a2", xlen, PARAM_OUT);
574 init_reg_param(®_params[3], "a3", xlen, PARAM_OUT);
575 init_reg_param(®_params[4], "a4", xlen, PARAM_OUT);
576 init_reg_param(®_params[5], "a5", xlen, PARAM_OUT);
579 cur_count = MIN(count, data_wa_size);
580 buf_set_u64(reg_params[0].value, 0, xlen, fespi_info->ctrl_base);
581 buf_set_u64(reg_params[1].value, 0, xlen, page_size);
582 buf_set_u64(reg_params[2].value, 0, xlen, data_wa->address);
583 buf_set_u64(reg_params[3].value, 0, xlen, offset);
584 buf_set_u64(reg_params[4].value, 0, xlen, cur_count);
585 buf_set_u64(reg_params[5].value, 0, xlen,
586 fespi_info->dev->pprog_cmd | (bank->size > 0x1000000 ? 0x100 : 0));
588 retval = target_write_buffer(target, data_wa->address, cur_count,
590 if (retval != ERROR_OK) {
591 LOG_DEBUG("Failed to write %d bytes to " TARGET_ADDR_FMT ": %d",
592 cur_count, data_wa->address, retval);
596 LOG_DEBUG("write(ctrl_base=0x%" TARGET_PRIxADDR ", page_size=0x%x, "
597 "address=0x%" TARGET_PRIxADDR ", offset=0x%" PRIx32
598 ", count=0x%" PRIx32 "), buffer=%02x %02x %02x %02x %02x %02x ..." PRIx32,
599 fespi_info->ctrl_base, page_size, data_wa->address, offset, cur_count,
600 buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]);
601 retval = target_run_algorithm(target, 0, NULL,
602 ARRAY_SIZE(reg_params), reg_params,
603 algorithm_wa->address, 0, cur_count * 2, NULL);
604 if (retval != ERROR_OK) {
605 LOG_ERROR("Failed to execute algorithm at " TARGET_ADDR_FMT ": %d",
606 algorithm_wa->address, retval);
610 uint64_t algorithm_result = buf_get_u64(reg_params[0].value, 0, xlen);
611 if (algorithm_result != 0) {
612 LOG_ERROR("Algorithm returned error %" PRId64, algorithm_result);
622 target_free_working_area(target, data_wa);
623 target_free_working_area(target, algorithm_wa);
626 fespi_txwm_wait(bank);
628 /* Disable Hardware accesses*/
629 if (fespi_disable_hw_mode(bank) != ERROR_OK)
633 retval = fespi_wip(bank, FESPI_PROBE_TIMEOUT);
634 if (retval != ERROR_OK)
637 uint32_t page_offset = offset % page_size;
638 /* central part, aligned words */
640 /* clip block at page boundary */
641 if (page_offset + count > page_size)
642 cur_count = page_size - page_offset;
646 retval = slow_fespi_write_buffer(bank, buffer, offset, cur_count);
647 if (retval != ERROR_OK)
656 /* Switch to HW mode before return to prompt */
657 if (fespi_enable_hw_mode(bank) != ERROR_OK)
664 target_free_working_area(target, data_wa);
665 target_free_working_area(target, algorithm_wa);
667 /* Switch to HW mode before return to prompt */
668 if (fespi_enable_hw_mode(bank) != ERROR_OK)
674 /* Return ID of flash device */
675 /* On exit, SW mode is kept */
676 static int fespi_read_flash_id(struct flash_bank *bank, uint32_t *id)
678 struct target *target = bank->target;
681 if (target->state != TARGET_HALTED) {
682 LOG_ERROR("Target not halted");
683 return ERROR_TARGET_NOT_HALTED;
686 fespi_txwm_wait(bank);
689 retval = fespi_wip(bank, FESPI_PROBE_TIMEOUT);
690 if (retval != ERROR_OK)
693 fespi_set_dir(bank, FESPI_DIR_RX);
695 /* Send SPI command "read ID" */
696 if (fespi_write_reg(bank, FESPI_REG_CSMODE, FESPI_CSMODE_HOLD) != ERROR_OK)
699 fespi_tx(bank, SPIFLASH_READ_ID);
700 /* Send dummy bytes to actually read the ID.*/
705 /* read ID from Receive Register */
707 if (fespi_rx(bank, NULL) != ERROR_OK)
710 if (fespi_rx(bank, &rx) != ERROR_OK)
713 if (fespi_rx(bank, &rx) != ERROR_OK)
716 if (fespi_rx(bank, &rx) != ERROR_OK)
720 if (fespi_write_reg(bank, FESPI_REG_CSMODE, FESPI_CSMODE_AUTO) != ERROR_OK)
723 fespi_set_dir(bank, FESPI_DIR_TX);
728 static int fespi_probe(struct flash_bank *bank)
730 struct target *target = bank->target;
731 struct fespi_flash_bank *fespi_info = bank->driver_priv;
732 struct flash_sector *sectors;
733 uint32_t id = 0; /* silence uninitialized warning */
734 const struct fespi_target *target_device;
738 if (fespi_info->probed)
740 fespi_info->probed = false;
742 if (fespi_info->ctrl_base == 0) {
743 for (target_device = target_devices ; target_device->name ; ++target_device)
744 if (target_device->tap_idcode == target->tap->idcode)
747 if (!target_device->name) {
748 LOG_ERROR("Device ID 0x%" PRIx32 " is not known as FESPI capable",
749 target->tap->idcode);
753 fespi_info->ctrl_base = target_device->ctrl_base;
755 LOG_DEBUG("Valid FESPI on device %s at address " TARGET_ADDR_FMT,
756 target_device->name, bank->base);
759 LOG_DEBUG("Assuming FESPI as specified at address " TARGET_ADDR_FMT
760 " with ctrl at " TARGET_ADDR_FMT, fespi_info->ctrl_base,
764 /* read and decode flash ID; returns in SW mode */
765 if (fespi_write_reg(bank, FESPI_REG_TXCTRL, FESPI_TXWM(1)) != ERROR_OK)
767 fespi_set_dir(bank, FESPI_DIR_TX);
769 /* Disable Hardware accesses*/
770 if (fespi_disable_hw_mode(bank) != ERROR_OK)
773 retval = fespi_read_flash_id(bank, &id);
775 if (fespi_enable_hw_mode(bank) != ERROR_OK)
777 if (retval != ERROR_OK)
780 fespi_info->dev = NULL;
781 for (const struct flash_device *p = flash_devices; p->name ; p++)
782 if (p->device_id == id) {
787 if (!fespi_info->dev) {
788 LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32 ")", id);
792 LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32 ")",
793 fespi_info->dev->name, fespi_info->dev->device_id);
795 /* Set correct size value */
796 bank->size = fespi_info->dev->size_in_bytes;
798 if (bank->size <= (1UL << 16))
799 LOG_WARNING("device needs 2-byte addresses - not implemented");
801 /* if no sectors, treat whole bank as single sector */
802 sectorsize = fespi_info->dev->sectorsize ?
803 fespi_info->dev->sectorsize : fespi_info->dev->size_in_bytes;
805 /* create and fill sectors array */
806 bank->num_sectors = fespi_info->dev->size_in_bytes / sectorsize;
807 sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
809 LOG_ERROR("not enough memory");
813 for (unsigned int sector = 0; sector < bank->num_sectors; sector++) {
814 sectors[sector].offset = sector * sectorsize;
815 sectors[sector].size = sectorsize;
816 sectors[sector].is_erased = -1;
817 sectors[sector].is_protected = 0;
820 bank->sectors = sectors;
821 fespi_info->probed = true;
825 static int fespi_auto_probe(struct flash_bank *bank)
827 struct fespi_flash_bank *fespi_info = bank->driver_priv;
828 if (fespi_info->probed)
830 return fespi_probe(bank);
833 static int fespi_protect_check(struct flash_bank *bank)
835 /* Nothing to do. Protection is only handled in SW. */
839 static int get_fespi_info(struct flash_bank *bank, struct command_invocation *cmd)
841 struct fespi_flash_bank *fespi_info = bank->driver_priv;
843 if (!(fespi_info->probed)) {
844 command_print_sameline(cmd, "\nFESPI flash bank not probed yet\n");
848 command_print_sameline(cmd, "\nFESPI flash information:\n"
849 " Device \'%s\' (ID 0x%08" PRIx32 ")\n",
850 fespi_info->dev->name, fespi_info->dev->device_id);
855 const struct flash_driver fespi_flash = {
857 .flash_bank_command = fespi_flash_bank_command,
858 .erase = fespi_erase,
859 .protect = fespi_protect,
860 .write = fespi_write,
861 .read = default_flash_read,
862 .probe = fespi_probe,
863 .auto_probe = fespi_auto_probe,
864 .erase_check = default_flash_blank_check,
865 .protect_check = fespi_protect_check,
866 .info = get_fespi_info,
867 .free_driver_priv = default_flash_free_driver_priv