diff --git a/boards/renesas/ek_ra8m1/doc/index.rst b/boards/renesas/ek_ra8m1/doc/index.rst index dce3b85a581..84b168eb23e 100644 --- a/boards/renesas/ek_ra8m1/doc/index.rst +++ b/boards/renesas/ek_ra8m1/doc/index.rst @@ -104,6 +104,8 @@ The below features are currently supported on Zephyr OS for EK-RA8M1 board: +-----------+------------+----------------------+ | SPI | on-chip | spi | +-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ Other hardware features are currently not supported by the port. diff --git a/boards/renesas/ek_ra8m1/ek_ra8m1.dts b/boards/renesas/ek_ra8m1/ek_ra8m1.dts index 114fe5516ad..730e6b3ced2 100644 --- a/boards/renesas/ek_ra8m1/ek_ra8m1.dts +++ b/boards/renesas/ek_ra8m1/ek_ra8m1.dts @@ -16,6 +16,7 @@ chosen { zephyr,sram = &sram0; + zephyr,flash-controller = &flash1; zephyr,flash = &flash0; zephyr,console = &uart9; zephyr,shell-uart = &uart9; @@ -169,3 +170,16 @@ mikrobus_serial: &uart3 {}; pinctrl-names = "default"; status = "okay"; }; + +&flash1 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@0 { + label = "storage"; + reg = <0X0 DT_SIZE_K(12)>; + }; + }; +}; diff --git a/boards/renesas/ek_ra8m1/ek_ra8m1_defconfig b/boards/renesas/ek_ra8m1/ek_ra8m1_defconfig index d68962b8c92..dca93f2b9e0 100644 --- a/boards/renesas/ek_ra8m1/ek_ra8m1_defconfig +++ b/boards/renesas/ek_ra8m1/ek_ra8m1_defconfig @@ -16,3 +16,5 @@ CONFIG_CONSOLE=y CONFIG_BUILD_OUTPUT_HEX=y CONFIG_BUILD_NO_GAP_FILL=y CONFIG_CLOCK_CONTROL=y + +CONFIG_FLASH=y diff --git a/drivers/flash/CMakeLists.txt b/drivers/flash/CMakeLists.txt index 3724524dad4..c82276611af 100644 --- a/drivers/flash/CMakeLists.txt +++ b/drivers/flash/CMakeLists.txt @@ -140,3 +140,8 @@ zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_NRF_RRAM soc_flash_nrf_rram.c) zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_NRF_MRAM soc_flash_nrf_mram.c) zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_NUMAKER_RMC soc_flash_numaker_rmc.c) zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_SI32 flash_si32.c) + +if(CONFIG_RA_FLASH_HP) + zephyr_library_sources(flash_hp_ra.c) + zephyr_library_sources_ifdef(CONFIG_FLASH_EX_OP_ENABLED flash_hp_ra_ex_op.c) +endif() diff --git a/drivers/flash/Kconfig b/drivers/flash/Kconfig index 658718e6d58..99f17d71f7a 100644 --- a/drivers/flash/Kconfig +++ b/drivers/flash/Kconfig @@ -237,6 +237,8 @@ source "drivers/flash/Kconfig.nrf_mram" source "drivers/flash/Kconfig.numaker_rmc" +source "drivers/flash/Kconfig.renesas_ra" + module = FLASH module-str = flash source "subsys/logging/Kconfig.template.log_config" diff --git a/drivers/flash/Kconfig.renesas_ra b/drivers/flash/Kconfig.renesas_ra new file mode 100644 index 00000000000..05512c0418b --- /dev/null +++ b/drivers/flash/Kconfig.renesas_ra @@ -0,0 +1,28 @@ +# Renesas RA Family + +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config RA_FLASH_HP + bool "RA flash driver" + depends on DT_HAS_RENESAS_RA_FLASH_HP_CONTROLLER_ENABLED + default y + select FLASH_HAS_DRIVER_ENABLED + select FLASH_PAGE_LAYOUT + select FLASH_HAS_PAGE_LAYOUT + select FLASH_HAS_EXPLICIT_ERASE + select FLASH_HAS_EX_OP if(SOC_SERIES_RA8M1) + select USE_RA_FSP_FLASH_HP + help + Enable flash driver for RA series + +if RA_FLASH_HP + +config FLASH_RA_WRITE_PROTECT + bool "Extended operation for flash write protection control" + default n + help + Enables flash extended operation to enable/disable flash write + protection from external devices + +endif # RA_FLASH_HP diff --git a/drivers/flash/flash_hp_ra.c b/drivers/flash/flash_hp_ra.c new file mode 100644 index 00000000000..2d832a65c93 --- /dev/null +++ b/drivers/flash/flash_hp_ra.c @@ -0,0 +1,397 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define LOG_LEVEL CONFIG_FLASH_LOG_LEVEL +#include +#include +#include +#include +#include +#include +#include +#include +#include "flash_hp_ra.h" + +#define DT_DRV_COMPAT renesas_ra_flash_hp_controller + +LOG_MODULE_REGISTER(flash_hp_ra, CONFIG_FLASH_LOG_LEVEL); + +#define ERASE_BLOCK_SIZE_0 DT_PROP(DT_INST(0, renesas_ra_nv_flash), erase_block_size) +#define ERASE_BLOCK_SIZE_1 DT_PROP(DT_INST(1, renesas_ra_nv_flash), erase_block_size) + +BUILD_ASSERT((ERASE_BLOCK_SIZE_0 % FLASH_HP_CF_BLOCK_8KB_SIZE) == 0, + "erase-block-size expected to be a multiple of a block size"); +BUILD_ASSERT((ERASE_BLOCK_SIZE_1 % FLASH_HP_DF_BLOCK_SIZE) == 0, + "erase-block-size expected to be a multiple of a block size"); + +/* Flags, set from Callback function */ +static volatile struct event_flash g_event_flash = { + .erase_complete = false, + .write_complete = false, +}; + +void fcu_frdyi_isr(void); +void fcu_fiferr_isr(void); + +static int flash_controller_ra_init(const struct device *dev); +static int flash_ra_init(const struct device *dev); +static int flash_ra_erase(const struct device *dev, off_t offset, size_t len); +static int flash_ra_read(const struct device *dev, off_t offset, void *data, size_t len); +static int flash_ra_write(const struct device *dev, off_t offset, const void *data, size_t len); +static const struct flash_parameters *flash_ra_get_parameters(const struct device *dev); +#ifdef CONFIG_FLASH_PAGE_LAYOUT +void flash_ra_page_layout(const struct device *dev, const struct flash_pages_layout **layout, + size_t *layout_size); +#endif + +#ifdef CONFIG_FLASH_EX_OP_ENABLED +static int flash_ra_ex_op(const struct device *dev, uint16_t code, const uintptr_t in, void *out); +#endif + +static const struct flash_driver_api flash_ra_api = { + .erase = flash_ra_erase, + .write = flash_ra_write, + .read = flash_ra_read, + .get_parameters = flash_ra_get_parameters, +#ifdef CONFIG_FLASH_PAGE_LAYOUT + .page_layout = flash_ra_page_layout, +#endif +#ifdef CONFIG_FLASH_EX_OP_ENABLED + .ex_op = flash_ra_ex_op, +#endif +}; + +static struct flash_pages_layout flash_ra_layout[5]; + +void bgo_callback(flash_callback_args_t *p_args) +{ + if (FLASH_EVENT_ERASE_COMPLETE == p_args->event) { + g_event_flash.erase_complete = true; + } else { + g_event_flash.write_complete = true; + } +} + +static bool flash_ra_valid_range(off_t area_size, off_t offset, size_t len) +{ + if ((offset < 0) || (offset >= area_size) || ((area_size - offset) < len)) { + return false; + } + + return true; +} + +static int flash_ra_read(const struct device *dev, off_t offset, void *data, size_t len) +{ + struct flash_hp_ra_data *flash_data = dev->data; + + if (!flash_ra_valid_range(flash_data->area_size, offset, len)) { + return -EINVAL; + } + + if (!len) { + return 0; + } + + LOG_DBG("flash: read 0x%lx, len: %u", (long)(offset + flash_data->area_address), len); + + memcpy(data, (uint8_t *)(offset + flash_data->area_address), len); + + return 0; +} + +static int flash_ra_erase(const struct device *dev, off_t offset, size_t len) +{ + struct flash_hp_ra_data *flash_data = dev->data; + struct flash_hp_ra_controller *dev_ctrl = flash_data->controller; + static struct flash_pages_info page_info_off, page_info_len; + fsp_err_t err = FSP_ERR_ASSERTION; + uint32_t block_num; + int rc, rc2; + + if (!flash_ra_valid_range(flash_data->area_size, offset, len)) { + return -EINVAL; + } + + if (!len) { + return 0; + } + + LOG_DBG("flash: erase 0x%lx, len: %u", (long)(offset + flash_data->area_address), len); + + rc = flash_get_page_info_by_offs(dev, offset, &page_info_off); + + if (rc != 0) { + return -EINVAL; + } + + if (offset != page_info_off.start_offset) { + return -EINVAL; + } + + rc2 = flash_get_page_info_by_offs(dev, (offset + len), &page_info_len); + if (rc2 != 0) { + return -EINVAL; + } + +#if defined(CONFIG_DUAL_BANK_MODE) + /* Invalid offset in dual bank mode, this is reversed area. */ + if ((page_info_off.index > FLASH_HP_CF_BLOCK_32KB_DUAL_LOW_END && + page_info_off.index < FLASH_HP_CF_BLOCK_8KB_HIGH_START) || + (page_info_len.index > FLASH_HP_CF_BLOCK_32KB_DUAL_LOW_END && + page_info_len.index < FLASH_HP_CF_BLOCK_8KB_HIGH_START)) { + return -EIO; + } +#endif + + if ((offset + len) != (page_info_len.start_offset)) { + return -EIO; + } + + block_num = (uint32_t)((page_info_len.index) - page_info_off.index); + + if (block_num > 0) { + k_sem_take(&dev_ctrl->ctrl_sem, K_FOREVER); + + err = R_FLASH_HP_Erase(&dev_ctrl->flash_ctrl, + (long)(flash_data->area_address + offset), block_num); + + if (err != FSP_SUCCESS) { + k_sem_give(&dev_ctrl->ctrl_sem); + return -EIO; + } + + if (flash_data->FlashRegion == DATA_FLASH) { + /* Wait for the erase complete event flag, if BGO is SET */ + if (true == dev_ctrl->fsp_config.data_flash_bgo) { + while (!g_event_flash.erase_complete) { + k_sleep(K_USEC(10)); + } + g_event_flash.erase_complete = false; + } + } + + k_sem_give(&dev_ctrl->ctrl_sem); + } + + return 0; +} + +static int flash_ra_write(const struct device *dev, off_t offset, const void *data, size_t len) +{ + fsp_err_t err = FSP_ERR_ASSERTION; + struct flash_hp_ra_data *flash_data = dev->data; + struct flash_hp_ra_controller *dev_ctrl = flash_data->controller; + + if (!flash_ra_valid_range(flash_data->area_size, offset, len)) { + return -EINVAL; + } + + if (!len) { + return 0; + } + + LOG_DBG("flash: write 0x%lx, len: %u", (long)(offset + flash_data->area_address), len); + + k_sem_take(&dev_ctrl->ctrl_sem, K_FOREVER); + + err = R_FLASH_HP_Write(&dev_ctrl->flash_ctrl, (uint32_t)data, + (long)(offset + flash_data->area_address), len); + + if (err != FSP_SUCCESS) { + k_sem_give(&dev_ctrl->ctrl_sem); + return -EIO; + } + + if (flash_data->FlashRegion == DATA_FLASH) { + /* Wait for the write complete event flag, if BGO is SET */ + if (true == dev_ctrl->fsp_config.data_flash_bgo) { + while (!g_event_flash.write_complete) { + k_sleep(K_USEC(10)); + } + g_event_flash.write_complete = false; + } + } + + k_sem_give(&dev_ctrl->ctrl_sem); + + return 0; +} + +void flash_ra_page_layout(const struct device *dev, const struct flash_pages_layout **layout, + size_t *layout_size) +{ + struct flash_hp_ra_data *flash_data = dev->data; + + if (flash_data->FlashRegion == DATA_FLASH) { + flash_ra_layout[0].pages_count = flash_data->area_size / FLASH_HP_DF_BLOCK_SIZE; + flash_ra_layout[0].pages_size = FLASH_HP_DF_BLOCK_SIZE; + + *layout_size = 1; + } else { +#if defined(CONFIG_DUAL_BANK_MODE) + flash_ra_layout[0].pages_count = + (FLASH_HP_CF_BLOCK_8KB_LOW_END - FLASH_HP_CF_BLOCK_8KB_LOW_START) + 1; + flash_ra_layout[0].pages_size = FLASH_HP_CF_BLOCK_8KB_SIZE; + + flash_ra_layout[1].pages_count = (FLASH_HP_CF_BLOCK_32KB_DUAL_LOW_END - + FLASH_HP_CF_BLOCK_32KB_DUAL_LOW_START) + + 1; + flash_ra_layout[1].pages_size = FLASH_HP_CF_BLOCK_32KB_SIZE; + + flash_ra_layout[2].pages_count = FLASH_RESERVED_AREA_NUM; + flash_ra_layout[2].pages_size = + (FLASH_HP_BANK2_OFFSET - + (flash_ra_layout[0].pages_count * flash_ra_layout[0].pages_size) - + (flash_ra_layout[1].pages_count * flash_ra_layout[1].pages_size)) / + FLASH_RESERVED_AREA_NUM; + + flash_ra_layout[3].pages_count = + (FLASH_HP_CF_BLOCK_8KB_HIGH_END - FLASH_HP_CF_BLOCK_8KB_HIGH_START) + 1; + flash_ra_layout[3].pages_size = FLASH_HP_CF_BLOCK_8KB_SIZE; + + /* The final block is the dummy block */ + flash_ra_layout[4].pages_count = (FLASH_HP_CF_BLOCK_32KB_DUAL_HIGH_END + 1 - + FLASH_HP_CF_BLOCK_32KB_DUAL_HIGH_START) + + 1; + flash_ra_layout[4].pages_size = FLASH_HP_CF_BLOCK_32KB_SIZE; + + *layout_size = 5; +#else + flash_ra_layout[0].pages_count = + (FLASH_HP_CF_BLOCK_8KB_LOW_END - FLASH_HP_CF_BLOCK_8KB_LOW_START) + 1; + flash_ra_layout[0].pages_size = FLASH_HP_CF_BLOCK_8KB_SIZE; + flash_ra_layout[1].pages_count = + (FLASH_HP_CF_BLOCK_32KB_LINEAR_END - FLASH_HP_CF_BLOCK_32KB_LINEAR_START) + + 1; + flash_ra_layout[1].pages_size = FLASH_HP_CF_BLOCK_32KB_SIZE; + + *layout_size = 2; +#endif + } + + *layout = flash_ra_layout; +} + +static const struct flash_parameters *flash_ra_get_parameters(const struct device *dev) +{ + const struct flash_hp_ra_config *config = dev->config; + + return &config->flash_ra_parameters; +} + +static struct flash_hp_ra_controller flash_hp_ra_controller = { + .fsp_config = { + .data_flash_bgo = true, + .p_callback = bgo_callback, + .p_context = NULL, + .irq = (IRQn_Type)DT_INST_IRQ_BY_NAME(0, frdyi, irq), + .err_irq = (IRQn_Type)DT_INST_IRQ_BY_NAME(0, fiferr, irq), + .err_ipl = DT_INST_IRQ_BY_NAME(0, fiferr, priority), + .ipl = DT_INST_IRQ_BY_NAME(0, frdyi, priority), + }}; + +#ifdef CONFIG_FLASH_EX_OP_ENABLED +static int flash_ra_ex_op(const struct device *dev, uint16_t code, const uintptr_t in, void *out) +{ + int err = -ENOTSUP; + + switch (code) { +#if defined(CONFIG_FLASH_RA_WRITE_PROTECT) + case FLASH_RA_EX_OP_WRITE_PROTECT: + err = flash_ra_ex_op_write_protect(dev, in, out); + break; +#endif /* CONFIG_FLASH_RA_WRITE_PROTECT */ + + default: + break; + } + + return err; +} +#endif + +static int flash_ra_init(const struct device *dev) +{ + const struct device *dev_ctrl = DEVICE_DT_INST_GET(0); + struct flash_hp_ra_data *flash_data = dev->data; + + if (!device_is_ready(dev_ctrl)) { + return -ENODEV; + } + + if (flash_data->area_address == FLASH_HP_DF_START) { + flash_data->FlashRegion = DATA_FLASH; + } else { + flash_data->FlashRegion = CODE_FLASH; + } + + flash_data->controller = dev_ctrl->data; + + return 0; +} + +static void flash_controller_ra_irq_config_func(const struct device *dev) +{ + ARG_UNUSED(dev); + + R_ICU->IELSR[DT_IRQ_BY_NAME(DT_DRV_INST(0), frdyi, irq)] = ELC_EVENT_FCU_FRDYI; + R_ICU->IELSR[DT_IRQ_BY_NAME(DT_DRV_INST(0), fiferr, irq)] = ELC_EVENT_FCU_FIFERR; + + IRQ_CONNECT(DT_IRQ_BY_NAME(DT_DRV_INST(0), frdyi, irq), + DT_IRQ_BY_NAME(DT_DRV_INST(0), frdyi, priority), fcu_frdyi_isr, + DEVICE_DT_INST_GET(0), 0); + IRQ_CONNECT(DT_IRQ_BY_NAME(DT_DRV_INST(0), fiferr, irq), + DT_IRQ_BY_NAME(DT_DRV_INST(0), fiferr, priority), fcu_fiferr_isr, + DEVICE_DT_INST_GET(0), 0); + + irq_enable(DT_INST_IRQ_BY_NAME(0, frdyi, irq)); + irq_enable(DT_INST_IRQ_BY_NAME(0, fiferr, irq)); +} + +static int flash_controller_ra_init(const struct device *dev) +{ + fsp_err_t err = FSP_SUCCESS; + const struct flash_hp_ra_controller_config *cfg = dev->config; + struct flash_hp_ra_controller *data = dev->data; + + cfg->irq_config(dev); + + err = R_FLASH_HP_Open(&data->flash_ctrl, &data->fsp_config); + + if (err != FSP_SUCCESS) { + LOG_DBG("flash: open error=%d", (int)err); + return -EIO; + } + + k_sem_init(&data->ctrl_sem, 1, 1); + + return 0; +} + +static struct flash_hp_ra_controller_config flash_hp_ra_controller_config = { + .irq_config = flash_controller_ra_irq_config_func, +}; + +#define RA_FLASH_INIT(index) \ + struct flash_hp_ra_data flash_hp_ra_data_##index = {.area_address = DT_REG_ADDR(index), \ + .area_size = DT_REG_SIZE(index)}; \ + static struct flash_hp_ra_config flash_hp_ra_config_##index = { \ + .flash_ra_parameters = { \ + .write_block_size = GET_SIZE( \ + (CHECK_EQ(DT_REG_ADDR(index), FLASH_HP_DF_START)), 4, 128), \ + .erase_value = 0xff, \ + }}; \ + \ + DEVICE_DT_DEFINE(index, flash_ra_init, NULL, &flash_hp_ra_data_##index, \ + &flash_hp_ra_config_##index, POST_KERNEL, CONFIG_FLASH_INIT_PRIORITY, \ + &flash_ra_api); + +DT_FOREACH_CHILD_STATUS_OKAY(DT_DRV_INST(0), RA_FLASH_INIT); + +/* define the flash controller device just to run the init. */ +DEVICE_DT_DEFINE(DT_DRV_INST(0), flash_controller_ra_init, NULL, &flash_hp_ra_controller, + &flash_hp_ra_controller_config, PRE_KERNEL_1, CONFIG_FLASH_INIT_PRIORITY, NULL); diff --git a/drivers/flash/flash_hp_ra.h b/drivers/flash/flash_hp_ra.h new file mode 100644 index 00000000000..54587e0a9b8 --- /dev/null +++ b/drivers/flash/flash_hp_ra.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_FLASH_RA_HP_H_ +#define ZEPHYR_DRIVERS_FLASH_RA_HP_H_ + +#include +#include +#include +#include + +#define CHECK_EQ(val1, val2) ((val1) == (val2) ? 1 : 0) +#define GET_SIZE(COND, value, default_value) ((COND) ? (value) : (default_value)) + +#define FLASH_HP_BANK2_OFFSET \ + (BSP_FEATURE_FLASH_HP_CF_DUAL_BANK_START - BSP_FEATURE_FLASH_CODE_FLASH_START) + +#define FLASH_HP_CF_BLOCK_8KB_SIZE BSP_FEATURE_FLASH_HP_CF_REGION0_BLOCK_SIZE +#define FLASH_HP_CF_BLOCK_32KB_SIZE BSP_FEATURE_FLASH_HP_CF_REGION1_BLOCK_SIZE +#define FLASH_HP_DF_BLOCK_SIZE BSP_FEATURE_FLASH_HP_DF_BLOCK_SIZE +#define FLASH_HP_DF_START BSP_FEATURE_FLASH_DATA_FLASH_START + +#define FLASH_HP_CF_BLOCK_8KB_LOW_START (0) +#define FLASH_HP_CF_BLOCK_8KB_LOW_END (7) +#define FLASH_HP_CF_BLOCK_8KB_HIGH_START (70) +#define FLASH_HP_CF_BLOCK_8KB_HIGH_END (77) + +#define FLASH_HP_CF_BLOCK_32KB_LINEAR_START (8) + +#define FLASH_HP_CF_BLOCK_32KB_DUAL_LOW_START (8) +#define FLASH_HP_CF_BLOCK_32KB_DUAL_HIGH_START (78) + +#if defined(CONFIG_SOC_R7FA8M1AHECBD) +#define FLASH_RESERVED_AREA_NUM (33) +#define FLASH_HP_CF_BLOCK_32KB_LINEAR_END (68) +#define FLASH_HP_CF_BLOCK_32KB_DUAL_LOW_END (36) +#define FLASH_HP_CF_BLOCK_32KB_DUAL_HIGH_END (106) +#endif + +#if defined(CONFIG_FLASH_EX_OP_ENABLED) +#define FLASH_HP_FCU_CONFIG_SET_BPS (0x1300A1C0U) +#define FLASH_HP_FCU_CONFIG_SET_BPS_SEC (0x0300A240U) +#define FLASH_HP_FCU_CONFIG_SET_BPS_SEL (0x0300A2C0U) + +#define FLASH_HP_FCU_CONFIG_SET_PBPS (0x1300A1E0U) +#define FLASH_HP_FCU_CONFIG_SET_PBPS_SEC (0x0300A260U) +#endif /* CONFIG_FLASH_EX_OP_ENABLED */ + +/* Zero based offset into g_configuration_area_data[] for BPS */ +#define FLASH_HP_FCU_CONFIG_SET_BPS_OFFSET (0U) + +enum flash_region { + CODE_FLASH, + DATA_FLASH, +}; + +typedef void (*irq_config_func_t)(const struct device *dev); + +struct flash_hp_ra_controller { + struct st_flash_hp_instance_ctrl flash_ctrl; + struct k_sem ctrl_sem; + struct st_flash_cfg fsp_config; +}; + +struct flash_hp_ra_controller_config { + irq_config_func_t irq_config; +}; + +struct flash_hp_ra_data { + struct flash_hp_ra_controller *controller; + enum flash_region FlashRegion; + uint32_t area_address; + uint32_t area_size; +}; + +struct flash_hp_ra_config { + struct flash_parameters flash_ra_parameters; +}; + +struct event_flash { + volatile bool erase_complete; + volatile bool write_complete; +}; + +#if defined(CONFIG_FLASH_RA_WRITE_PROTECT) +int flash_ra_ex_op_write_protect(const struct device *dev, const uintptr_t in, void *out); +#endif /*CONFIG_FLASH_RA_WRITE_PROTECT*/ + +#endif /* ZEPHYR_DRIVERS_FLASH_RA_HP_H_ */ diff --git a/drivers/flash/flash_hp_ra_ex_op.c b/drivers/flash/flash_hp_ra_ex_op.c new file mode 100644 index 00000000000..42cc4c81b1c --- /dev/null +++ b/drivers/flash/flash_hp_ra_ex_op.c @@ -0,0 +1,379 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#ifdef CONFIG_USERSPACE +#include +#include +#endif + +#include +#include "flash_hp_ra.h" + +#define FLASH_HP_CONFIG_SET_ACCESS_WORD_CNT (8U) + +#if (DT_PROP(DT_NODELABEL(flash0), renesas_programming_enable)) +extern uint16_t g_configuration_area_data[FLASH_HP_CONFIG_SET_ACCESS_WORD_CNT]; +#endif +extern fsp_err_t +flash_hp_enter_pe_cf_mode(flash_hp_instance_ctrl_t *const p_ctrl) PLACE_IN_RAM_SECTION; + +extern fsp_err_t flash_hp_stop(void) PLACE_IN_RAM_SECTION; + +extern fsp_err_t flash_hp_configuration_area_write(flash_hp_instance_ctrl_t *p_ctrl, + uint32_t fsaddr) PLACE_IN_RAM_SECTION; + +extern fsp_err_t flash_hp_check_errors(fsp_err_t previous_error, uint32_t error_bits, + fsp_err_t return_error) PLACE_IN_RAM_SECTION; + +extern fsp_err_t flash_hp_pe_mode_exit(void) PLACE_IN_RAM_SECTION; + +static fsp_err_t flash_hp_set_block_protect_ns(flash_hp_instance_ctrl_t *p_ctrl, + uint8_t *bps_val_ns, uint8_t *pbps_val_ns, + uint32_t size) PLACE_IN_RAM_SECTION; + +static fsp_err_t flash_hp_set_block_protect_sec(flash_hp_instance_ctrl_t *p_ctrl, + uint8_t *bps_val_sec, uint8_t *pbps_val_sec, + uint32_t size) PLACE_IN_RAM_SECTION; + +static fsp_err_t flash_hp_set_block_protect_sel(flash_hp_instance_ctrl_t *p_ctrl, + uint8_t *bps_sel_val, + uint32_t size) PLACE_IN_RAM_SECTION; + +static fsp_err_t flash_hp_set_block_protect_ns(flash_hp_instance_ctrl_t *p_ctrl, + uint8_t *bps_val_ns, uint8_t *pbps_val_ns, + uint32_t size) +{ + /* Disable interrupts to prevent vector table access while code flash is in P/E mode. */ + int key = irq_lock(); + + /* Update Flash state and enter Code Flash P/E mode */ + fsp_err_t err = flash_hp_enter_pe_cf_mode(p_ctrl); + + FSP_ERROR_RETURN(err == FSP_SUCCESS, err); + + memset(g_configuration_area_data, UINT8_MAX, sizeof(g_configuration_area_data)); + if (bps_val_ns != NULL) { + memcpy(&g_configuration_area_data[FLASH_HP_FCU_CONFIG_SET_BPS_OFFSET], bps_val_ns, + size); + err = flash_hp_configuration_area_write(p_ctrl, FLASH_HP_FCU_CONFIG_SET_BPS); + err = flash_hp_check_errors(err, 0, FSP_ERR_WRITE_FAILED); + } + + memset(g_configuration_area_data, UINT8_MAX, sizeof(g_configuration_area_data)); + if (pbps_val_ns != NULL) { + memcpy(&g_configuration_area_data[FLASH_HP_FCU_CONFIG_SET_BPS_OFFSET], pbps_val_ns, + size); + err = flash_hp_configuration_area_write(p_ctrl, FLASH_HP_FCU_CONFIG_SET_PBPS); + err = flash_hp_check_errors(err, 0, FSP_ERR_WRITE_FAILED); + } + + /* Return to read mode*/ + fsp_err_t pe_exit_err = flash_hp_pe_mode_exit(); + + if (err == FSP_SUCCESS) { + err = pe_exit_err; + } + + /* Enable interrupts after code flash operations are complete. */ + irq_unlock(key); + + return err; +} + +static fsp_err_t flash_hp_set_block_protect_sec(flash_hp_instance_ctrl_t *p_ctrl, + uint8_t *bps_val_sec, uint8_t *pbps_val_sec, + uint32_t size) +{ + /* Disable interrupts to prevent vector table access while code flash is in P/E mode. */ + int key = irq_lock(); + /* Update Flash state and enter Code Flash P/E mode */ + fsp_err_t err = flash_hp_enter_pe_cf_mode(p_ctrl); + + FSP_ERROR_RETURN(err == FSP_SUCCESS, err); + + memset(g_configuration_area_data, UINT8_MAX, sizeof(g_configuration_area_data)); + if (bps_val_sec != NULL) { + memcpy(&g_configuration_area_data[FLASH_HP_FCU_CONFIG_SET_BPS_OFFSET], bps_val_sec, + size); + err = flash_hp_configuration_area_write(p_ctrl, FLASH_HP_FCU_CONFIG_SET_BPS_SEC); + err = flash_hp_check_errors(err, 0, FSP_ERR_WRITE_FAILED); + } + + memset(g_configuration_area_data, UINT8_MAX, sizeof(g_configuration_area_data)); + if (pbps_val_sec != NULL) { + memcpy(&g_configuration_area_data[FLASH_HP_FCU_CONFIG_SET_BPS_OFFSET], pbps_val_sec, + size); + err = flash_hp_configuration_area_write(p_ctrl, FLASH_HP_FCU_CONFIG_SET_PBPS_SEC); + err = flash_hp_check_errors(err, 0, FSP_ERR_WRITE_FAILED); + } + + /* Return to read mode*/ + fsp_err_t pe_exit_err = flash_hp_pe_mode_exit(); + + if (err == FSP_SUCCESS) { + err = pe_exit_err; + } + + /* Enable interrupts after code flash operations are complete. */ + irq_unlock(key); + + return err; +} + +static fsp_err_t flash_hp_set_block_protect_sel(flash_hp_instance_ctrl_t *p_ctrl, + uint8_t *bps_sel_val, uint32_t size) +{ + /* Disable interrupts to prevent vector table access while code flash is in P/E mode. */ + int key = irq_lock(); + + /* Update Flash state and enter Code Flash P/E mode */ + fsp_err_t err = flash_hp_enter_pe_cf_mode(p_ctrl); + + FSP_ERROR_RETURN(err == FSP_SUCCESS, err); + + memset(g_configuration_area_data, UINT8_MAX, sizeof(g_configuration_area_data)); + memcpy(&g_configuration_area_data[FLASH_HP_FCU_CONFIG_SET_BPS_OFFSET], bps_sel_val, size); + err = flash_hp_configuration_area_write(p_ctrl, FLASH_HP_FCU_CONFIG_SET_BPS_SEL); + err = flash_hp_check_errors(err, 0, FSP_ERR_WRITE_FAILED); + + /* Return to read mode*/ + fsp_err_t pe_exit_err = flash_hp_pe_mode_exit(); + + if (err == FSP_SUCCESS) { + err = pe_exit_err; + } + + /* Enable interrupts after code flash operations are complete. */ + irq_unlock(key); + + return err; +} + +static fsp_err_t R_FLASH_HP_BlockProtectSet(flash_ctrl_t *const p_api_ctrl, uint8_t *bps_val_ns, + uint8_t *bps_val_sec, uint8_t *bps_val_sel, + uint8_t *pbps_val_ns, uint8_t *pbps_val_sec, + uint32_t size); + +static fsp_err_t R_FLASH_HP_BlockProtectGet(flash_ctrl_t *const p_api_ctrl, uint32_t *bps_val_ns, + uint32_t *bps_val_sec, uint8_t *bps_val_sel, + uint8_t *pbps_val_ns, uint8_t *pbps_val_sec, + uint32_t *size); + +int flash_ra_block_protect_set(const struct device *dev, + const struct flash_ra_ex_write_protect_in *request); + +int flash_ra_block_protect_get(const struct device *dev, + struct flash_ra_ex_write_protect_out *response); + +static fsp_err_t R_FLASH_HP_BlockProtectSet(flash_ctrl_t *const p_api_ctrl, uint8_t *bps_val_ns, + uint8_t *bps_val_sec, uint8_t *bps_val_sel, + uint8_t *pbps_val_ns, uint8_t *pbps_val_sec, + uint32_t size) +{ + flash_hp_instance_ctrl_t *p_ctrl = (flash_hp_instance_ctrl_t *)p_api_ctrl; + fsp_err_t err = FSP_SUCCESS; + +#if (DT_PROP(DT_NODELABEL(flash0), renesas_programming_enable)) + + /* if non-secure BPS (PBPS) buffers are not null and size is smaller than 16 bytes */ + if (((bps_val_ns != NULL) || (pbps_val_ns != NULL)) && + (size <= (sizeof(uint16_t) * FLASH_HP_CONFIG_SET_ACCESS_WORD_CNT))) { + err = flash_hp_set_block_protect_ns(p_ctrl, bps_val_ns, pbps_val_ns, size); + } + + /* if secure BPS (PBPS) buffers are not null and size is smaller than 16 bytes */ + if (((bps_val_sec != NULL) || (pbps_val_sec != NULL)) && + (size <= (sizeof(uint16_t) * FLASH_HP_CONFIG_SET_ACCESS_WORD_CNT))) { + err = flash_hp_set_block_protect_sec(p_ctrl, bps_val_sec, pbps_val_sec, size); + } + + /* if BPS SEL buffer is not null and size is smaller than 16 bytes */ + if ((bps_val_sel != NULL) && + (size <= (sizeof(uint16_t) * FLASH_HP_CONFIG_SET_ACCESS_WORD_CNT))) { + err = flash_hp_set_block_protect_sel(p_ctrl, bps_val_sel, size); + } +#else + + err = FSP_ERR_UNSUPPORTED; /* For consistency with _LP API we return error if Code Flash */ + +#endif + + return err; +} + +static fsp_err_t R_FLASH_HP_BlockProtectGet(flash_ctrl_t *const p_api_ctrl, uint32_t *bps_val_ns, + uint32_t *bps_val_sec, uint8_t *bps_val_sel, + uint8_t *pbps_val_ns, uint8_t *pbps_val_sec, + uint32_t *size) +{ + fsp_err_t err = FSP_ERR_UNSUPPORTED; + +#if (DT_PROP(DT_NODELABEL(flash0), renesas_programming_enable)) + + err = FSP_SUCCESS; + + if (bps_val_ns != NULL) { + bps_val_ns[0] = *((uint32_t *)(FLASH_HP_FCU_CONFIG_SET_BPS + 0)); + bps_val_ns[1] = *((uint32_t *)(FLASH_HP_FCU_CONFIG_SET_BPS + 3)); + bps_val_ns[2] = *((uint32_t *)(FLASH_HP_FCU_CONFIG_SET_BPS + 7)); + bps_val_ns[3] = *((uint32_t *)(FLASH_HP_FCU_CONFIG_SET_BPS + 11)); + } + + if (bps_val_sec != NULL) { + bps_val_sec[0] = *((uint32_t *)(FLASH_HP_FCU_CONFIG_SET_BPS_SEC + 0)); + bps_val_sec[1] = *((uint32_t *)(FLASH_HP_FCU_CONFIG_SET_BPS_SEC + 3)); + bps_val_sec[2] = *((uint32_t *)(FLASH_HP_FCU_CONFIG_SET_BPS_SEC + 7)); + bps_val_sec[3] = *((uint32_t *)(FLASH_HP_FCU_CONFIG_SET_BPS_SEC + 11)); + } + + if (bps_val_sel != NULL) { + bps_val_sel[0] = *((uint32_t *)(FLASH_HP_FCU_CONFIG_SET_BPS_SEL + 0)); + bps_val_sel[1] = *((uint32_t *)(FLASH_HP_FCU_CONFIG_SET_BPS_SEL + 3)); + bps_val_sel[2] = *((uint32_t *)(FLASH_HP_FCU_CONFIG_SET_BPS_SEL + 7)); + bps_val_sel[3] = *((uint32_t *)(FLASH_HP_FCU_CONFIG_SET_BPS_SEL + 11)); + } + + if (pbps_val_ns != NULL) { + pbps_val_ns[0] = *((uint32_t *)(FLASH_HP_FCU_CONFIG_SET_PBPS + 0)); + pbps_val_ns[1] = *((uint32_t *)(FLASH_HP_FCU_CONFIG_SET_PBPS + 3)); + pbps_val_ns[2] = *((uint32_t *)(FLASH_HP_FCU_CONFIG_SET_PBPS + 7)); + pbps_val_ns[3] = *((uint32_t *)(FLASH_HP_FCU_CONFIG_SET_PBPS + 11)); + } + + if (pbps_val_sec != NULL) { + pbps_val_sec[0] = *((uint32_t *)(FLASH_HP_FCU_CONFIG_SET_PBPS_SEC + 0)); + pbps_val_sec[1] = *((uint32_t *)(FLASH_HP_FCU_CONFIG_SET_PBPS_SEC + 3)); + pbps_val_sec[2] = *((uint32_t *)(FLASH_HP_FCU_CONFIG_SET_PBPS_SEC + 7)); + pbps_val_sec[3] = *((uint32_t *)(FLASH_HP_FCU_CONFIG_SET_PBPS_SEC + 11)); + } + + if (size != NULL) { + *size = 4; + } +#endif + + FSP_PARAMETER_NOT_USED(p_api_ctrl); + + return err; +} + +#if defined(CONFIG_FLASH_RA_WRITE_PROTECT) +int flash_ra_block_protect_get(const struct device *dev, + struct flash_ra_ex_write_protect_out *response) +{ + fsp_err_t err = FSP_ERR_ASSERTION; + struct flash_hp_ra_data *flash_data = dev->data; + struct flash_hp_ra_controller *dev_ctrl = flash_data->controller; + flash_ra_cf_block_map bps_ns; + + /* get the current non-secure BPS register values */ + err = R_FLASH_HP_BlockProtectGet(&dev_ctrl->flash_ctrl, (uint32_t *)&bps_ns, NULL, NULL, + NULL, NULL, NULL); + memcpy(&response->protected_enabled, &bps_ns, sizeof(flash_ra_cf_block_map)); + + return err; +} + +int flash_ra_ex_op_write_protect(const struct device *dev, const uintptr_t in, void *out) +{ + const struct flash_ra_ex_write_protect_in *request = + (const struct flash_ra_ex_write_protect_in *)in; + struct flash_ra_ex_write_protect_out *result = (struct flash_ra_ex_write_protect_out *)out; + + int rc = 0, rc2 = 0; +#ifdef CONFIG_USERSPACE + bool syscall_trap = z_syscall_trap(); +#endif + + if (request != NULL) { +#ifdef CONFIG_USERSPACE + struct flash_ra_ex_write_protect_in copy_in; + + if (syscall_trap) { + Z_OOPS(z_user_from_copy(©_in, request, sizeof(copy_in))); + request = ©_in; + } +#endif + /* if both enable and disable are set */ + if ((request->protect_enable.BPS[0] & request->protect_disable.BPS[0]) || + (request->protect_enable.BPS[1] & request->protect_disable.BPS[1]) || + (request->protect_enable.BPS[2] & request->protect_disable.BPS[2]) || + (request->protect_enable.BPS[3] & request->protect_disable.BPS[3])) { + return EINVAL; + } + + rc = flash_ra_block_protect_set(dev, request); + } + + if (result != NULL) { +#ifdef CONFIG_USERSPACE + struct flash_ra_ex_write_protect_out copy_out; + + if (syscall_trap) { + result = ©_out; + } +#endif + rc2 = flash_ra_block_protect_get(dev, result); + if (!rc) { + rc = rc2; + } + +#ifdef CONFIG_USERSPACE + if (syscall_trap) { + Z_OOPS(z_user_to_copy(out, result, sizeof(copy_out))); + } +#endif + } + + return rc; +} + +int flash_ra_block_protect_set(const struct device *dev, + const struct flash_ra_ex_write_protect_in *request) +{ + fsp_err_t err = FSP_ERR_ASSERTION; + struct flash_hp_ra_data *flash_data = dev->data; + struct flash_hp_ra_controller *dev_ctrl = flash_data->controller; + flash_ra_cf_block_map bps_ns; + + /* get the current non-secure BPS register values */ + err = R_FLASH_HP_BlockProtectGet(&dev_ctrl->flash_ctrl, (uint32_t *)&bps_ns, NULL, NULL, + NULL, NULL, NULL); + + if (err != FSP_SUCCESS) { + __ASSERT(false, "flash: block get current value error =%d", err); + return -EIO; + } + + /* enable block protect */ + bps_ns.BPS[0] &= ~(request->protect_enable.BPS[0]); + bps_ns.BPS[1] &= ~(request->protect_enable.BPS[1]); + bps_ns.BPS[2] &= ~(request->protect_enable.BPS[2]); + bps_ns.BPS[3] &= ~(request->protect_enable.BPS[3]); + + /* disable block protect */ + bps_ns.BPS[0] |= (request->protect_disable.BPS[0]); + bps_ns.BPS[1] |= (request->protect_disable.BPS[1]); + bps_ns.BPS[2] |= (request->protect_disable.BPS[2]); + bps_ns.BPS[3] |= (request->protect_disable.BPS[3]); + + /* reset default all from non-secure */ + err = R_FLASH_HP_BlockProtectSet(&dev_ctrl->flash_ctrl, (uint8_t *)&bps_ns, NULL, NULL, + NULL, NULL, sizeof(bps_ns)); + + if (err != FSP_SUCCESS) { + __ASSERT(false, "flash: block protect error=%d", err); + return -EIO; + } + return 0; +} + +#endif /* CONFIG_FLASH_RA_WRITE_PROTECT */ diff --git a/dts/arm/renesas/ra/ra8/r7fa8m1ahecbd.dtsi b/dts/arm/renesas/ra/ra8/r7fa8m1ahecbd.dtsi index 4fc8a972923..aecc48d9fa4 100644 --- a/dts/arm/renesas/ra/ra8/r7fa8m1ahecbd.dtsi +++ b/dts/arm/renesas/ra/ra8/r7fa8m1ahecbd.dtsi @@ -8,10 +8,21 @@ / { soc { - flash-controller@407fe000 { + flash-controller@40100000 { flash0: flash@2000000 { - compatible = "soc-nv-flash"; - reg = <0x02000000 DT_SIZE_M(2)>; + compatible = "renesas,ra-nv-flash"; + reg = <0x02000000 DT_SIZE_K(2016)>; + write-block-size = <128>; + erase-block-size = <8192>; + renesas,programming-enable; + }; + + flash1: flash@27000000 { + compatible = "renesas,ra-nv-flash"; + reg = <0x27000000 DT_SIZE_K(12)>; + write-block-size = <4>; + erase-block-size = <64>; + renesas,programming-enable; }; }; }; diff --git a/dts/arm/renesas/ra/ra8/ra8x1.dtsi b/dts/arm/renesas/ra/ra8/ra8x1.dtsi index 3cf329ad48a..589adc00dba 100644 --- a/dts/arm/renesas/ra/ra8/ra8x1.dtsi +++ b/dts/arm/renesas/ra/ra8/ra8x1.dtsi @@ -271,10 +271,13 @@ }; }; - flash-controller@407fe000 { - reg = <0x407fe000 0x1000>; + flash: flash-controller@40100000 { + compatible = "renesas,ra-flash-hp-controller"; + reg = <0x40100000 0x20000>; #address-cells = <1>; #size-cells = <1>; + interrupts = <38 2>, <39 2>; + interrupt-names = "frdyi", "fiferr"; }; adc0: adc@40332000 { diff --git a/dts/bindings/flash_controller/renesas,ra-flash-hp-controller.yaml b/dts/bindings/flash_controller/renesas,ra-flash-hp-controller.yaml new file mode 100644 index 00000000000..cefba7e4486 --- /dev/null +++ b/dts/bindings/flash_controller/renesas,ra-flash-hp-controller.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA family flash high-performance controller + +compatible: "renesas,ra-flash-hp-controller" + +include: flash-controller.yaml diff --git a/dts/bindings/mtd/renesas,ra-nv-flash.yaml b/dts/bindings/mtd/renesas,ra-nv-flash.yaml new file mode 100644 index 00000000000..8e9e763546b --- /dev/null +++ b/dts/bindings/mtd/renesas,ra-nv-flash.yaml @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: | + Flash memory binding of Renesas RA family + +include: [base.yaml, soc-nv-flash.yaml] + +compatible: "renesas,ra-nv-flash" + +properties: + renesas,programming-enable: + type: boolean + description: Enable flash programming configuration diff --git a/include/zephyr/drivers/flash/ra_flash_api_extensions.h b/include/zephyr/drivers/flash/ra_flash_api_extensions.h new file mode 100644 index 00000000000..465c98ac83c --- /dev/null +++ b/include/zephyr/drivers/flash/ra_flash_api_extensions.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ZEPHYR_INCLUDE_DRIVERS_FLASH_RA_EXTENSIONS_H__ +#define __ZEPHYR_INCLUDE_DRIVERS_FLASH_RA_EXTENSIONS_H__ + +#include + +enum ra_ex_ops { + FLASH_RA_EX_OP_WRITE_PROTECT = FLASH_EX_OP_VENDOR_BASE, +}; + +typedef struct { + union { + uint32_t BPS[4]; + + struct { + uint32_t b000: 1; + uint32_t b001: 1; + uint32_t b002: 1; + uint32_t b003: 1; + uint32_t b004: 1; + uint32_t b005: 1; + uint32_t b006: 1; + uint32_t b007: 1; + uint32_t b008: 1; + uint32_t b009: 1; + uint32_t b010: 1; + uint32_t b011: 1; + uint32_t b012: 1; + uint32_t b013: 1; + uint32_t b014: 1; + uint32_t b015: 1; + uint32_t b016: 1; + uint32_t b017: 1; + uint32_t b018: 1; + uint32_t b019: 1; + uint32_t b020: 1; + uint32_t b021: 1; + uint32_t b022: 1; + uint32_t b023: 1; + uint32_t b024: 1; + uint32_t b025: 1; + uint32_t b026: 1; + uint32_t b027: 1; + uint32_t b028: 1; + uint32_t b029: 1; + uint32_t b030: 1; + uint32_t b031: 1; + uint32_t b032: 1; + uint32_t b033: 1; + uint32_t b034: 1; + uint32_t b035: 1; + uint32_t b036: 1; + uint32_t b037: 1; + uint32_t b038: 1; + uint32_t b039: 1; + uint32_t b040: 1; + uint32_t b041: 1; + uint32_t b042: 1; + uint32_t b043: 1; + uint32_t b044: 1; + uint32_t b045: 1; + uint32_t b046: 1; + uint32_t b047: 1; + uint32_t b048: 1; + uint32_t b049: 1; + uint32_t b050: 1; + uint32_t b051: 1; + uint32_t b052: 1; + uint32_t b053: 1; + uint32_t b054: 1; + uint32_t b055: 1; + uint32_t b056: 1; + uint32_t b057: 1; + uint32_t b058: 1; + uint32_t b059: 1; + uint32_t b060: 1; + uint32_t b061: 1; + uint32_t b062: 1; + uint32_t b063: 1; + uint32_t b064: 1; + uint32_t b065: 1; + uint32_t b066: 1; + uint32_t b067: 1; + uint32_t b068: 1; + uint32_t b069: 1; + uint32_t b070: 1; + uint32_t b071: 1; + uint32_t b072: 1; + uint32_t b073: 1; + uint32_t b074: 1; + uint32_t b075: 1; + uint32_t b076: 1; + uint32_t b077: 1; + uint32_t b078: 1; + uint32_t b079: 1; + uint32_t b080: 1; + uint32_t b081: 1; + uint32_t b082: 1; + uint32_t b083: 1; + uint32_t b084: 1; + uint32_t b085: 1; + uint32_t b086: 1; + uint32_t b087: 1; + uint32_t b088: 1; + uint32_t b089: 1; + uint32_t b090: 1; + uint32_t b091: 1; + uint32_t b092: 1; + uint32_t b093: 1; + uint32_t b094: 1; + uint32_t b095: 1; + uint32_t b096: 1; + uint32_t b097: 1; + uint32_t b098: 1; + uint32_t b099: 1; + uint32_t b100: 1; + uint32_t b101: 1; + uint32_t b102: 1; + uint32_t b103: 1; + uint32_t b104: 1; + uint32_t b105: 1; + uint32_t b106: 1; + uint32_t: 21; + } BPS_b; + }; +} flash_ra_cf_block_map; + +#if defined(CONFIG_FLASH_RA_WRITE_PROTECT) +typedef struct flash_ra_ex_write_protect_in { + flash_ra_cf_block_map protect_enable; + flash_ra_cf_block_map protect_disable; + flash_ra_cf_block_map protect_permanent; +} flash_ra_ex_write_protect_in_t; + +typedef struct flash_ra_ex_write_protect_out { + flash_ra_cf_block_map protected_enabled; + flash_ra_cf_block_map protected_premanent; +} flash_ra_ex_write_protect_out_t; +#endif /* CONFIG_FLASH_RA_WRITE_PROTECT */ + +#endif diff --git a/modules/Kconfig.renesas_fsp b/modules/Kconfig.renesas_fsp index 2e7482d2a25..24d55866e76 100644 --- a/modules/Kconfig.renesas_fsp +++ b/modules/Kconfig.renesas_fsp @@ -53,3 +53,8 @@ config USE_RA_FSP_SPI_B bool help Enable RA FSP SPI-B driver + +config USE_RA_FSP_FLASH_HP + bool + help + Enable RA FSP FLASH HP driver diff --git a/soc/renesas/ra/ra8m1/Kconfig.defconfig b/soc/renesas/ra/ra8m1/Kconfig.defconfig index 524d19358bc..426625e0295 100644 --- a/soc/renesas/ra/ra8m1/Kconfig.defconfig +++ b/soc/renesas/ra/ra8m1/Kconfig.defconfig @@ -9,4 +9,8 @@ config NUM_IRQS config PINCTRL default y +# Set to the minimal size of data which can be written. +config FLASH_FILL_BUFFER_SIZE + default 128 + endif # SOC_SERIES_RA8M1 diff --git a/soc/renesas/ra/ra8m1/Kconfig.soc b/soc/renesas/ra/ra8m1/Kconfig.soc index ae3913973f4..889e457eaf7 100644 --- a/soc/renesas/ra/ra8m1/Kconfig.soc +++ b/soc/renesas/ra/ra8m1/Kconfig.soc @@ -19,3 +19,9 @@ config SOC_SERIES config SOC default "r7fa8m1ahecbd" if SOC_R7FA8M1AHECBD + +config DUAL_BANK_MODE + bool "Dual bank mode" + default n + help + Enable dual bank mode diff --git a/tests/drivers/flash/common/boards/ek_ra8m1.overlay b/tests/drivers/flash/common/boards/ek_ra8m1.overlay new file mode 100644 index 00000000000..8e42c66387c --- /dev/null +++ b/tests/drivers/flash/common/boards/ek_ra8m1.overlay @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +/delete-node/ &storage_partition; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Set the 2 last block of storage. */ + storage_partition: partition@1E8000 { + label = "storage"; + reg = <0x1E8000 DT_SIZE_K(64)>; + }; + }; +};