1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Copyright (c) 2024 ENE Technology Inc.
12 #include <helper/time_support.h>
13 #include <helper/bits.h>
14 #include <target/target.h>
15 #include <flash/nor/core.h>
16 #include <flash/nor/driver.h>
17 #include <flash/nor/spi.h>
19 #define ISPICFG 0x0000
20 #define ISPISTS 0x0004
21 #define ISPIADDR 0x0008
22 #define ISPICMD 0x000C
23 #define ISPIDAT 0x0100
25 #define ISPISTS_BUSY BIT(0)
26 #define STATUS1_QE BIT(1)
28 #define CFG_READ 0x372
29 #define CFG_WRITE 0x371
31 #define ISPI_CTRL_BASE 0x50101000
33 /* name read qread page erase chip device_id page erase flash
34 * _cmd _cmd _prog _cmd* _erase size size* size
37 struct flash_device ene_flash_device
=
38 FLASH_ID("ISPI flash", 0x03, 0x00, 0x02, 0x20, 0x60, 0x00132085, 0x100, 0x1000, 0x80000);
40 struct eneispif_flash_bank
{
42 target_addr_t ctrl_base
;
44 const struct flash_device
*dev
;
47 FLASH_BANK_COMMAND_HANDLER(eneispif_flash_bank_command
)
49 struct eneispif_flash_bank
*eneispif_info
;
51 LOG_DEBUG("%s", __func__
);
54 return ERROR_COMMAND_SYNTAX_ERROR
;
56 eneispif_info
= malloc(sizeof(struct eneispif_flash_bank
));
58 LOG_ERROR("not enough memory");
62 bank
->driver_priv
= eneispif_info
;
63 eneispif_info
->probed
= false;
64 eneispif_info
->ctrl_base
= ISPI_CTRL_BASE
;
66 COMMAND_PARSE_ADDRESS(CMD_ARGV
[6], eneispif_info
->ctrl_base
);
67 LOG_INFO("ASSUMING ISPI device at ctrl_base = " TARGET_ADDR_FMT
,
68 eneispif_info
->ctrl_base
);
74 static int eneispif_read_reg(struct flash_bank
*bank
, uint32_t *value
, target_addr_t address
)
76 struct target
*target
= bank
->target
;
77 struct eneispif_flash_bank
*eneispif_info
= bank
->driver_priv
;
79 int result
= target_read_u32(target
, eneispif_info
->ctrl_base
+ address
, value
);
80 if (result
!= ERROR_OK
) {
81 LOG_ERROR("%s error at " TARGET_ADDR_FMT
, __func__
,
82 eneispif_info
->ctrl_base
+ address
);
85 LOG_DEBUG("Read address " TARGET_ADDR_FMT
" = 0x%" PRIx32
,
86 eneispif_info
->ctrl_base
+ address
, *value
);
90 static int eneispif_write_reg(struct flash_bank
*bank
, target_addr_t address
, uint32_t value
)
92 struct target
*target
= bank
->target
;
93 struct eneispif_flash_bank
*eneispif_info
= bank
->driver_priv
;
95 LOG_DEBUG("Write address " TARGET_ADDR_FMT
" = 0x%" PRIx32
,
96 eneispif_info
->ctrl_base
+ address
, value
);
97 int result
= target_write_u32(target
, eneispif_info
->ctrl_base
+ address
, value
);
98 if (result
!= ERROR_OK
) {
99 LOG_ERROR("%s error writing 0x%" PRIx32
" to " TARGET_ADDR_FMT
, __func__
,
100 value
, eneispif_info
->ctrl_base
+ address
);
106 static int eneispif_wait(struct flash_bank
*bank
)
108 int64_t start
= timeval_ms();
113 if (eneispif_read_reg(bank
, &status
, ISPISTS
) != ERROR_OK
)
116 if (!(status
& ISPISTS_BUSY
))
119 int64_t now
= timeval_ms();
120 if (now
- start
> 1000) {
121 LOG_ERROR("Busy more than 1000ms.");
122 return ERROR_TARGET_TIMEOUT
;
129 static int eneispi_erase_sector(struct flash_bank
*bank
, int sector
)
131 int retval
= ERROR_OK
;
132 struct eneispif_flash_bank
*eneispif_info
= bank
->driver_priv
;
136 retval
= eneispif_read_reg(bank
, &conf
, ISPICFG
);
137 if (retval
!= ERROR_OK
)
140 offset
= bank
->sectors
[sector
].offset
;
141 retval
= eneispif_write_reg(bank
, ISPIADDR
, offset
); /* Address */
142 if (retval
!= ERROR_OK
)
145 eneispif_write_reg(bank
, ISPICFG
, CFG_WRITE
); /* Cmmmand enable */
146 eneispif_write_reg(bank
, ISPICMD
, SPIFLASH_WRITE_ENABLE
); /* Write enable */
147 retval
= eneispif_write_reg(bank
, ISPICMD
, eneispif_info
->dev
->erase_cmd
); /* Erase page */
148 if (retval
!= ERROR_OK
)
151 retval
= eneispif_wait(bank
);
152 if (retval
!= ERROR_OK
)
156 eneispif_write_reg(bank
, ISPICFG
, conf
); /* restore */
160 static int eneispif_erase(struct flash_bank
*bank
, unsigned int first
, unsigned int last
)
162 struct target
*target
= bank
->target
;
163 struct eneispif_flash_bank
*eneispif_info
= bank
->driver_priv
;
164 int retval
= ERROR_OK
;
166 LOG_DEBUG("%s: from sector %u to sector %u", __func__
, first
, last
);
168 if (target
->state
!= TARGET_HALTED
) {
169 LOG_ERROR("Target not halted");
170 return ERROR_TARGET_NOT_HALTED
;
173 if (last
< first
|| last
>= bank
->num_sectors
) {
174 LOG_ERROR("Flash sector invalid");
175 return ERROR_FLASH_SECTOR_INVALID
;
178 if (!(eneispif_info
->probed
)) {
179 LOG_ERROR("Flash bank not probed");
180 return ERROR_FLASH_BANK_NOT_PROBED
;
183 for (unsigned int sector
= first
; sector
<= last
; sector
++) {
184 if (bank
->sectors
[sector
].is_protected
) {
185 LOG_ERROR("Flash sector %u protected", sector
);
190 if (eneispif_info
->dev
->erase_cmd
== 0x00)
191 return ERROR_FLASH_OPER_UNSUPPORTED
;
193 for (unsigned int sector
= first
; sector
<= last
; sector
++) {
194 retval
= eneispi_erase_sector(bank
, sector
);
195 if (retval
!= ERROR_OK
)
202 static int eneispif_protect(struct flash_bank
*bank
, int set
, unsigned int first
, unsigned int last
)
204 for (unsigned int sector
= first
; sector
<= last
; sector
++)
205 bank
->sectors
[sector
].is_protected
= set
;
210 static int eneispif_write(struct flash_bank
*bank
, const uint8_t *buffer
, uint32_t offset
,
213 struct target
*target
= bank
->target
;
214 struct eneispif_flash_bank
*eneispif_info
= bank
->driver_priv
;
217 int retval
= ERROR_OK
;
219 LOG_DEBUG("bank->size=0x%x offset=0x%08" PRIx32
" count=0x%08" PRIx32
, bank
->size
, offset
,
222 if (target
->state
!= TARGET_HALTED
) {
223 LOG_ERROR("Target not halted");
224 return ERROR_TARGET_NOT_HALTED
;
227 if (offset
+ count
> eneispif_info
->dev
->size_in_bytes
) {
228 LOG_WARNING("Write past end of flash. Extra data discarded.");
229 count
= eneispif_info
->dev
->size_in_bytes
- offset
;
232 /* Check sector protection */
233 for (unsigned int sector
= 0; sector
< bank
->num_sectors
; sector
++) {
234 /* Start offset in or before this sector? */
235 /* End offset in or behind this sector? */
236 if ((offset
< (bank
->sectors
[sector
].offset
+ bank
->sectors
[sector
].size
)) &&
237 ((offset
+ count
- 1) >= bank
->sectors
[sector
].offset
) &&
238 bank
->sectors
[sector
].is_protected
) {
239 LOG_ERROR("Flash sector %u protected", sector
);
244 retval
= eneispif_read_reg(bank
, &conf
, ISPICFG
);
245 if (retval
!= ERROR_OK
)
248 eneispif_write_reg(bank
, ISPICFG
, CFG_WRITE
); // Cmmmand enable
250 /* If no valid page_size, use reasonable default. */
252 eneispif_info
->dev
->pagesize
? eneispif_info
->dev
->pagesize
: SPIFLASH_DEF_PAGESIZE
;
253 uint32_t page_offset
= offset
% page_size
;
258 /* clip block at page boundary */
259 if (page_offset
+ count
> page_size
)
260 cur_count
= page_size
- page_offset
;
264 eneispif_write_reg(bank
, ISPICMD
, SPIFLASH_WRITE_ENABLE
); /* Write enable */
265 target_write_buffer(target
, eneispif_info
->ctrl_base
+ ISPIDAT
, cur_count
, buffer
);
266 eneispif_write_reg(bank
, ISPIADDR
, offset
);
267 retval
= eneispif_write_reg(bank
, ISPICMD
,
268 (cur_count
<< 16) | eneispif_info
->dev
->pprog_cmd
);
269 if (retval
!= ERROR_OK
)
276 retval
= eneispif_wait(bank
);
277 if (retval
!= ERROR_OK
)
282 eneispif_write_reg(bank
, ISPICFG
, conf
); /* restore */
286 /* Return ID of flash device */
287 /* On exit, SW mode is kept */
288 static int eneispif_read_flash_id(struct flash_bank
*bank
, uint32_t *id
)
290 struct eneispif_flash_bank
*eneispif_info
= bank
->driver_priv
;
291 struct target
*target
= bank
->target
;
293 uint32_t conf
, value
;
296 if (target
->state
!= TARGET_HALTED
) {
297 LOG_ERROR("Target not halted");
298 return ERROR_TARGET_NOT_HALTED
;
301 retval
= eneispif_read_reg(bank
, &conf
, ISPICFG
);
302 if (retval
!= ERROR_OK
)
305 LOG_DEBUG("ISPCFG = (0x%08" PRIx32
")", conf
);
307 /* read ID from Receive Register */
308 eneispif_write_reg(bank
, ISPICFG
, CFG_WRITE
); /* Cmmmand enable */
309 retval
= eneispif_write_reg(bank
, ISPICMD
, (3 << 16) | SPIFLASH_READ_ID
);
310 if (retval
!= ERROR_OK
)
313 retval
= eneispif_wait(bank
);
314 if (retval
!= ERROR_OK
)
317 retval
= target_read_buffer(target
, eneispif_info
->ctrl_base
+ ISPIDAT
, 3, buffer
);
318 if (retval
!= ERROR_OK
)
320 value
= (buffer
[2] << 16) | (buffer
[1] << 8) | buffer
[0];
321 LOG_DEBUG("ISPDAT = (0x%08" PRIx32
")", value
);
325 eneispif_write_reg(bank
, ISPICFG
, conf
); // restore
329 static int eneispif_probe(struct flash_bank
*bank
)
331 struct eneispif_flash_bank
*eneispif_info
= bank
->driver_priv
;
332 struct flash_sector
*sectors
;
337 if (eneispif_info
->probed
)
340 eneispif_info
->probed
= false;
342 LOG_INFO("Assuming ISPI flash at address " TARGET_ADDR_FMT
343 " with controller at " TARGET_ADDR_FMT
,
344 bank
->base
, eneispif_info
->ctrl_base
);
346 eneispif_write_reg(bank
, ISPICFG
, CFG_READ
); /* RAM map enable */
348 retval
= eneispif_read_flash_id(bank
, &id
);
349 if (retval
!= ERROR_OK
)
352 eneispif_info
->dev_id
= id
;
353 eneispif_info
->dev
= &ene_flash_device
;
355 LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32
")", eneispif_info
->dev
->name
,
356 eneispif_info
->dev_id
);
358 /* Set correct size value */
359 bank
->size
= eneispif_info
->dev
->size_in_bytes
;
361 if (bank
->size
<= (1UL << 16))
362 LOG_WARNING("device needs 2-byte addresses - not implemented");
364 /* if no sectors, treat whole bank as single sector */
365 sectorsize
= eneispif_info
->dev
->sectorsize
? eneispif_info
->dev
->sectorsize
366 : eneispif_info
->dev
->size_in_bytes
;
368 /* create and fill sectors array */
369 bank
->num_sectors
= eneispif_info
->dev
->size_in_bytes
/ sectorsize
;
370 sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
372 LOG_ERROR("not enough memory");
376 for (unsigned int sector
= 0; sector
< bank
->num_sectors
; sector
++) {
377 sectors
[sector
].offset
= sector
* sectorsize
;
378 sectors
[sector
].size
= sectorsize
;
379 sectors
[sector
].is_erased
= -1;
380 sectors
[sector
].is_protected
= 0;
383 bank
->sectors
= sectors
;
384 eneispif_info
->probed
= true;
388 static int eneispif_auto_probe(struct flash_bank
*bank
)
390 struct eneispif_flash_bank
*eneispif_info
= bank
->driver_priv
;
391 if (eneispif_info
->probed
)
393 return eneispif_probe(bank
);
396 static int eneispif_protect_check(struct flash_bank
*bank
)
398 /* Nothing to do. Protection is only handled in SW. */
402 static int get_eneispif_info(struct flash_bank
*bank
, struct command_invocation
*cmd
)
404 struct eneispif_flash_bank
*eneispif_info
= bank
->driver_priv
;
406 if (!(eneispif_info
->probed
)) {
407 command_print(cmd
, "ENE ISPI flash bank not probed yet.");
412 "ENE ISPI flash information:\n"
413 " Device \'%s\' (ID 0x%08" PRIx32
")",
414 eneispif_info
->dev
->name
, eneispif_info
->dev_id
);
419 const struct flash_driver eneispif_flash
= {
421 .usage
= "flash bank <name> 'eneispif' <base_address> <size> 0 0 <target> <ctrl_base>",
422 .flash_bank_command
= eneispif_flash_bank_command
,
423 .erase
= eneispif_erase
,
424 .protect
= eneispif_protect
,
425 .write
= eneispif_write
,
426 .read
= default_flash_read
,
427 .probe
= eneispif_probe
,
428 .auto_probe
= eneispif_auto_probe
,
429 .erase_check
= default_flash_blank_check
,
430 .protect_check
= eneispif_protect_check
,
431 .info
= get_eneispif_info
,
432 .free_driver_priv
= default_flash_free_driver_priv
,