summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriabdalkader <i.abdalkader@gmail.com>2025-01-08 15:12:18 +0100
committerDamien George <damien@micropython.org>2025-04-09 00:22:32 +1000
commit602bc86b6d8ebd200029568c060b878146050da1 (patch)
tree3bb466475c9c22d6368e186d45b92c9ea27764d7
parentdf06bf91a5a78c89eaa7b6b7d157df83c576553f (diff)
alif/ospi_flash: Use OSPI in XIP mode only.
The OSPI controller supports concurrent direct/XIP accesses, there's no need to disable XIP on direct access. In addition to improving the performance, this change lays the groundwork for supporting access by the HP and HE cores simultaneously. Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
-rw-r--r--ports/alif/ospi_flash.c39
-rw-r--r--ports/alif/ospi_flash.h4
2 files changed, 12 insertions, 31 deletions
diff --git a/ports/alif/ospi_flash.c b/ports/alif/ospi_flash.c
index d5aa99f2b..7400a678b 100644
--- a/ports/alif/ospi_flash.c
+++ b/ports/alif/ospi_flash.c
@@ -55,9 +55,6 @@ typedef struct _ospi_flash_t {
static ospi_flash_t global_flash;
-static int ospi_flash_xip_enter(ospi_flash_t *self);
-static int ospi_flash_xip_exit(ospi_flash_t *self);
-
/******************************************************************************/
// Generic SPI-flash helper functions.
@@ -188,6 +185,7 @@ int ospi_flash_mx_init(ospi_flash_t *self) {
break;
}
}
+
ospi_flash_wren_spi(self);
uint8_t buf0[6] = {cmd_wrcr2, 0, 0, 3, 0, ddc_value};
ospi_spi_transfer(&self->cfg, sizeof(buf0), buf0, buf0);
@@ -355,7 +353,7 @@ uintptr_t ospi_flash_get_xip_base(void) {
return (uintptr_t)self->cfg.xip_base;
}
-static int ospi_flash_xip_enter(ospi_flash_t *self) {
+int ospi_flash_xip_enter(ospi_flash_t *self) {
if (!self->xip_active) {
uint32_t irq_state = disable_irq();
self->xip_active = true;
@@ -366,7 +364,7 @@ static int ospi_flash_xip_enter(ospi_flash_t *self) {
return 0;
}
-static int ospi_flash_xip_exit(ospi_flash_t *self) {
+int ospi_flash_xip_exit(ospi_flash_t *self) {
if (self->xip_active) {
uint32_t irq_state = disable_irq();
ospi_xip_exit_ext(&self->cfg, self->set->inst_len, self->set->read_command, self->set->read_command);
@@ -382,43 +380,23 @@ static int ospi_flash_xip_exit(ospi_flash_t *self) {
int ospi_flash_erase_sector(uint32_t addr) {
ospi_flash_t *self = &global_flash;
- ospi_flash_xip_exit(self);
-
ospi_flash_write_cmd(self, self->set->write_en);
int ret = ospi_flash_wait_wel1(self);
if (ret < 0) {
- ospi_flash_xip_enter(self);
return ret;
}
ospi_flash_write_cmd_addr(self, self->set->erase_command, OSPI_ADDR_L_32bit, addr);
ret = ospi_flash_wait_wip0(self);
- ospi_flash_xip_enter(self);
+ SCB_InvalidateDCache_by_Addr(global_flash.cfg.xip_base + addr, MICROPY_HW_FLASH_BLOCK_SIZE_BYTES);
return ret;
}
int ospi_flash_read(uint32_t addr, uint32_t len, uint8_t *dest) {
- // OSPI FIFO is limited to 256 bytes. Need DMA to get a longer read.
- // Note that direct reading is much faster than using XIP memory-mapped read.
ospi_flash_t *self = &global_flash;
-
- ospi_flash_xip_exit(self);
-
- while (len) {
- uint32_t l = len / 4;
- if (l > 256) {
- l = 256;
- }
- ospi_setup_read_ext(&self->cfg, self->set->rxds, self->set->inst_len, OSPI_ADDR_L_32bit, OSPI_DATA_L_32bit, l, self->set->read_dummy_cycles);
- ospi_push(&self->cfg, self->set->read_command);
- ospi_recv_blocking_32bit_data(&self->cfg, addr, (uint32_t *)dest);
- addr += l * 4;
- len -= l * 4;
- dest += l * 4;
- }
-
- ospi_flash_xip_enter(self);
+ // Perform an XIP read (memcpy)
+ memcpy(dest, (void *)self->cfg.xip_base + addr, len);
return 0;
}
@@ -448,10 +426,9 @@ static int ospi_flash_write_page(uint32_t addr, uint32_t len, const uint8_t *src
}
int ospi_flash_write(uint32_t addr, uint32_t len, const uint8_t *src) {
- ospi_flash_xip_exit(&global_flash);
-
int ret = 0;
uint32_t offset = addr & (PAGE_SIZE - 1);
+
while (len) {
size_t rest = PAGE_SIZE - offset;
if (rest > len) {
@@ -467,7 +444,7 @@ int ospi_flash_write(uint32_t addr, uint32_t len, const uint8_t *src) {
offset = 0;
}
- ospi_flash_xip_enter(&global_flash);
+ SCB_InvalidateDCache_by_Addr(global_flash.cfg.xip_base + addr, len);
return ret;
}
diff --git a/ports/alif/ospi_flash.h b/ports/alif/ospi_flash.h
index affa4e610..0095ee2d4 100644
--- a/ports/alif/ospi_flash.h
+++ b/ports/alif/ospi_flash.h
@@ -89,6 +89,10 @@ uint8_t ospi_flash_mx_read_cr2(struct _ospi_flash_t *self, uint32_t addr);
int ospi_flash_mx_write_cr(struct _ospi_flash_t *self, uint8_t value);
int ospi_flash_mx_write_cr2(struct _ospi_flash_t *self, uint32_t addr, uint8_t value);
+// XIP control
+int ospi_flash_xip_enter(struct _ospi_flash_t *self);
+int ospi_flash_xip_exit(struct _ospi_flash_t *self);
+
// SPI flash interface.
int ospi_flash_init(void);
uintptr_t ospi_flash_get_xip_base(void);