drivers: flash: Add support for Apollo510 flash controller

This commit adds support for Apollo510 SoC in ambiq flash driver

Signed-off-by: Hao Luo <hluo@ambiq.com>
This commit is contained in:
Hao Luo 2025-02-12 11:53:40 +08:00 committed by Benjamin Cabé
commit 4bc2de23a9

View file

@ -18,11 +18,11 @@ LOG_MODULE_REGISTER(flash_ambiq, CONFIG_FLASH_LOG_LEVEL);
#define SOC_NV_FLASH_NODE DT_INST(0, soc_nv_flash)
#define SOC_NV_FLASH_ADDR DT_REG_ADDR(SOC_NV_FLASH_NODE)
#define SOC_NV_FLASH_SIZE DT_REG_SIZE(SOC_NV_FLASH_NODE)
#if (CONFIG_SOC_SERIES_APOLLO4X)
#define MIN_WRITE_SIZE 16
#else
#if (CONFIG_SOC_SERIES_APOLLO3X)
#define MIN_WRITE_SIZE 4
#endif /* CONFIG_SOC_SERIES_APOLLO4X */
#else
#define MIN_WRITE_SIZE 16
#endif
#define FLASH_WRITE_BLOCK_SIZE MAX(DT_PROP(SOC_NV_FLASH_NODE, write_block_size), MIN_WRITE_SIZE)
#define FLASH_ERASE_BLOCK_SIZE DT_PROP(SOC_NV_FLASH_NODE, erase_block_size)
@ -48,7 +48,7 @@ static struct k_sem flash_ambiq_sem;
static const struct flash_parameters flash_ambiq_parameters = {
.write_block_size = FLASH_WRITE_BLOCK_SIZE,
.erase_value = FLASH_ERASE_BYTE,
#if defined(CONFIG_SOC_SERIES_APOLLO4X)
#if !defined(CONFIG_SOC_SERIES_APOLLO3X)
.caps = {
.no_explicit_erase = true,
},
@ -113,17 +113,17 @@ static int flash_ambiq_write(const struct device *dev, off_t offset, const void
aligned[j] = UNALIGNED_GET((uint32_t *)src);
src++;
}
#if (CONFIG_SOC_SERIES_APOLLO4X)
ret = am_hal_mram_main_program(
AM_HAL_MRAM_PROGRAM_KEY, aligned,
(uint32_t *)(SOC_NV_FLASH_ADDR + offset + i * FLASH_WRITE_BLOCK_SIZE),
FLASH_WRITE_BLOCK_SIZE / sizeof(uint32_t));
#elif (CONFIG_SOC_SERIES_APOLLO3X)
#if defined(CONFIG_SOC_SERIES_APOLLO3X)
ret = am_hal_flash_program_main(
AM_HAL_FLASH_PROGRAM_KEY, aligned,
(uint32_t *)(SOC_NV_FLASH_ADDR + offset + i * FLASH_WRITE_BLOCK_SIZE),
FLASH_WRITE_BLOCK_SIZE / sizeof(uint32_t));
#endif /* CONFIG_SOC_SERIES_APOLLO4X */
#else
ret = am_hal_mram_main_program(
AM_HAL_MRAM_PROGRAM_KEY, aligned,
(uint32_t *)(SOC_NV_FLASH_ADDR + offset + i * FLASH_WRITE_BLOCK_SIZE),
FLASH_WRITE_BLOCK_SIZE / sizeof(uint32_t));
#endif
if (ret) {
break;
}
@ -150,9 +150,7 @@ static int flash_ambiq_erase(const struct device *dev, off_t offset, size_t len)
return 0;
}
#if (CONFIG_SOC_SERIES_APOLLO4X)
/* The erase address and length alignment check will be done in HAL.*/
#elif (CONFIG_SOC_SERIES_APOLLO3X)
#if defined(CONFIG_SOC_SERIES_APOLLO3X)
if ((offset % FLASH_ERASE_BLOCK_SIZE) != 0) {
LOG_ERR("offset 0x%lx is not on a page boundary", (long)offset);
return -EINVAL;
@ -162,15 +160,13 @@ static int flash_ambiq_erase(const struct device *dev, off_t offset, size_t len)
LOG_ERR("len %zu is not multiple of a page size", len);
return -EINVAL;
}
#endif /* CONFIG_SOC_SERIES_APOLLO4X */
#else
/* The erase address and length alignment check will be done in HAL.*/
#endif
FLASH_SEM_TAKE();
#if (CONFIG_SOC_SERIES_APOLLO4X)
ret = am_hal_mram_main_fill(AM_HAL_MRAM_PROGRAM_KEY, FLASH_ERASE_WORD,
(uint32_t *)(SOC_NV_FLASH_ADDR + offset),
(len / sizeof(uint32_t)));
#elif (CONFIG_SOC_SERIES_APOLLO3X)
#if defined(CONFIG_SOC_SERIES_APOLLO3X)
unsigned int key = 0;
key = irq_lock();
@ -181,7 +177,11 @@ static int flash_ambiq_erase(const struct device *dev, off_t offset, size_t len)
AM_HAL_FLASH_ADDR2PAGE(((uint32_t)SOC_NV_FLASH_ADDR + offset)));
irq_unlock(key);
#endif /* CONFIG_SOC_SERIES_APOLLO4X */
#else
ret = am_hal_mram_main_fill(AM_HAL_MRAM_PROGRAM_KEY, FLASH_ERASE_WORD,
(uint32_t *)(SOC_NV_FLASH_ADDR + offset),
(len / sizeof(uint32_t)));
#endif
FLASH_SEM_GIVE();