drivers: flash: Add Infineon CAT1 Flash driver
- Added initial version of Infineon CAT1 Flash driver - Added binding file for infineon,cat1-flash-controller.yaml - Added overlays for subsys/nvs and drivers/flash_shell to support cy8cproto_063_ble, cy8cproto_062_4343w boards - Defined erase-block-size in PSoC6 MPN dtsi. Signed-off-by: Sreeram Tatapudi <sreeram.praveen@infineon.com>
This commit is contained in:
parent
883e40db51
commit
98858f1e6a
|
@ -86,3 +86,4 @@ zephyr_library_include_directories_ifdef(
|
|||
|
||||
zephyr_library_sources_ifdef(CONFIG_FLASH_SHELL flash_shell.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_FLASH_JESD216 jesd216.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_FLASH_INFINEON_CAT1 flash_ifx_cat1.c)
|
||||
|
|
|
@ -148,4 +148,6 @@ source "drivers/flash/Kconfig.gd32"
|
|||
|
||||
source "drivers/flash/Kconfig.xmc4xxx"
|
||||
|
||||
source "drivers/flash/Kconfig.ifx_cat1"
|
||||
|
||||
endif # FLASH
|
||||
|
|
22
drivers/flash/Kconfig.ifx_cat1
Normal file
22
drivers/flash/Kconfig.ifx_cat1
Normal file
|
@ -0,0 +1,22 @@
|
|||
# Infineon CAT1 Flash configuration options
|
||||
|
||||
# Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or
|
||||
# an affiliate of Cypress Semiconductor Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config FLASH_INFINEON_CAT1
|
||||
bool "Infineon CAT1 FLASH driver"
|
||||
default y
|
||||
depends on DT_HAS_INFINEON_CAT1_FLASH_CONTROLLER_ENABLED
|
||||
select FLASH_HAS_PAGE_LAYOUT
|
||||
select FLASH_HAS_DRIVER_ENABLED
|
||||
select USE_INFINEON_FLASH
|
||||
help
|
||||
Enable the Flash driver for Infineon CAT1 family.
|
||||
|
||||
|
||||
config MPU_ALLOW_FLASH_WRITE
|
||||
bool "Add MPU access to write to flash"
|
||||
help
|
||||
Enable this to allow MPU RWX access to flash memory.
|
204
drivers/flash/flash_ifx_cat1.c
Normal file
204
drivers/flash/flash_ifx_cat1.c
Normal file
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
* Copyright 2023 Cypress Semiconductor Corporation (an Infineon company) or
|
||||
* an affiliate of Cypress Semiconductor Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT infineon_cat1_flash_controller
|
||||
#define SOC_NV_FLASH_NODE DT_PARENT(DT_INST(0, fixed_partitions))
|
||||
|
||||
#define PAGE_LEN DT_PROP(SOC_NV_FLASH_NODE, erase_block_size)
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/devicetree.h>
|
||||
#include <zephyr/drivers/flash.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
|
||||
#include "cyhal_flash.h"
|
||||
|
||||
LOG_MODULE_REGISTER(flash_infineon_cat1, CONFIG_FLASH_LOG_LEVEL);
|
||||
|
||||
/* Device config structure */
|
||||
struct ifx_cat1_flash_config {
|
||||
uint32_t base_addr;
|
||||
uint32_t max_addr;
|
||||
};
|
||||
|
||||
/* Data structure */
|
||||
struct ifx_cat1_flash_data {
|
||||
cyhal_flash_t flash_obj;
|
||||
struct k_sem sem;
|
||||
};
|
||||
|
||||
static struct flash_parameters ifx_cat1_flash_parameters = {
|
||||
.write_block_size = DT_PROP(SOC_NV_FLASH_NODE, write_block_size),
|
||||
.erase_value = 0x00,
|
||||
};
|
||||
|
||||
static inline void flash_ifx_sem_take(const struct device *dev)
|
||||
{
|
||||
struct ifx_cat1_flash_data *data = dev->data;
|
||||
|
||||
k_sem_take(&data->sem, K_FOREVER);
|
||||
}
|
||||
|
||||
static inline void flash_ifx_sem_give(const struct device *dev)
|
||||
{
|
||||
struct ifx_cat1_flash_data *data = dev->data;
|
||||
|
||||
k_sem_give(&data->sem);
|
||||
}
|
||||
|
||||
static int ifx_cat1_flash_read(const struct device *dev, off_t offset, void *data, size_t data_len)
|
||||
{
|
||||
struct ifx_cat1_flash_data *dev_data = dev->data;
|
||||
const struct ifx_cat1_flash_config *dev_config = dev->config;
|
||||
uint32_t read_offset = dev_config->base_addr + offset;
|
||||
cy_rslt_t rslt = CY_RSLT_SUCCESS;
|
||||
int ret = 0;
|
||||
|
||||
flash_ifx_sem_take(dev);
|
||||
|
||||
rslt = cyhal_flash_read(&dev_data->flash_obj, read_offset, (uint8_t *)data, data_len);
|
||||
if (rslt != CY_RSLT_SUCCESS) {
|
||||
LOG_ERR("Error reading @ 0x%x (Err:0x%x)", read_offset, rslt);
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
flash_ifx_sem_give(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ifx_cat1_flash_write(const struct device *dev, off_t offset, const void *data,
|
||||
size_t data_len)
|
||||
{
|
||||
struct ifx_cat1_flash_data *dev_data = dev->data;
|
||||
const struct ifx_cat1_flash_config *dev_config = dev->config;
|
||||
uint32_t write_offset = dev_config->base_addr + (uint32_t)offset;
|
||||
const uint8_t *data_ptr = (const uint8_t *)data;
|
||||
cy_rslt_t rslt = CY_RSLT_SUCCESS;
|
||||
int ret = 0;
|
||||
|
||||
if (data_len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((offset < 0) || (data_len % PAGE_LEN != 0) || (offset % PAGE_LEN != 0)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
flash_ifx_sem_take(dev);
|
||||
|
||||
while (data_len) {
|
||||
rslt = cyhal_flash_write(&dev_data->flash_obj, write_offset,
|
||||
(const uint32_t *)data_ptr);
|
||||
if (rslt != CY_RSLT_SUCCESS) {
|
||||
LOG_ERR("Error in writing @ 0x%x (Err:0x%x)", write_offset, rslt);
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
data_ptr += PAGE_LEN;
|
||||
write_offset += PAGE_LEN;
|
||||
data_len -= PAGE_LEN;
|
||||
}
|
||||
|
||||
out:
|
||||
flash_ifx_sem_give(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ifx_cat1_flash_erase(const struct device *dev, off_t offset, size_t size)
|
||||
{
|
||||
struct ifx_cat1_flash_data *data = dev->data;
|
||||
const struct ifx_cat1_flash_config *config = dev->config;
|
||||
uint32_t erase_offset = config->base_addr + (uint32_t)offset;
|
||||
cy_rslt_t rslt;
|
||||
|
||||
if ((offset < 0) || ((offset % PAGE_LEN) != 0)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (((erase_offset + size) > config->max_addr) || ((size % PAGE_LEN) != 0)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
while (size) {
|
||||
rslt = cyhal_flash_erase(&data->flash_obj, erase_offset);
|
||||
if (rslt != CY_RSLT_SUCCESS) {
|
||||
LOG_ERR("Error in erasing : 0x%x", rslt);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
size -= PAGE_LEN;
|
||||
erase_offset += PAGE_LEN;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if CONFIG_FLASH_PAGE_LAYOUT
|
||||
static const struct flash_pages_layout ifx_cat1_flash_pages_layout = {
|
||||
.pages_count = DT_REG_SIZE(SOC_NV_FLASH_NODE) / PAGE_LEN,
|
||||
.pages_size = PAGE_LEN,
|
||||
};
|
||||
|
||||
static void ifx_cat1_flash_page_layout(const struct device *dev,
|
||||
const struct flash_pages_layout **layout,
|
||||
size_t *layout_size)
|
||||
{
|
||||
*layout = &ifx_cat1_flash_pages_layout;
|
||||
|
||||
/*
|
||||
* For flash memories which have uniform page sizes, this routine
|
||||
* returns an array of length 1, which specifies the page size and
|
||||
* number of pages in the memory.
|
||||
*/
|
||||
*layout_size = 1;
|
||||
}
|
||||
#endif /* CONFIG_FLASH_PAGE_LAYOUT */
|
||||
|
||||
static const struct flash_parameters *ifx_cat1_flash_get_parameters(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
return &ifx_cat1_flash_parameters;
|
||||
}
|
||||
|
||||
static int ifx_cat1_flash_init(const struct device *dev)
|
||||
{
|
||||
struct ifx_cat1_flash_data *data = dev->data;
|
||||
cy_rslt_t rslt = CY_RSLT_SUCCESS;
|
||||
|
||||
rslt = cyhal_flash_init(&data->flash_obj);
|
||||
if (rslt != CY_RSLT_SUCCESS) {
|
||||
LOG_ERR("Failed to init flash hal driver (Err:0x%x)", rslt);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
k_sem_init(&data->sem, 1, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct flash_driver_api ifx_cat1_flash_driver_api = {
|
||||
.read = ifx_cat1_flash_read,
|
||||
.write = ifx_cat1_flash_write,
|
||||
.erase = ifx_cat1_flash_erase,
|
||||
.get_parameters = ifx_cat1_flash_get_parameters,
|
||||
#ifdef CONFIG_FLASH_PAGE_LAYOUT
|
||||
.page_layout = ifx_cat1_flash_page_layout,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct ifx_cat1_flash_data flash_data;
|
||||
|
||||
static const struct ifx_cat1_flash_config ifx_cat1_flash_config = {
|
||||
.base_addr = DT_REG_ADDR(SOC_NV_FLASH_NODE),
|
||||
.max_addr = DT_REG_ADDR(SOC_NV_FLASH_NODE) + DT_REG_SIZE(SOC_NV_FLASH_NODE)};
|
||||
|
||||
DEVICE_DT_INST_DEFINE(0, ifx_cat1_flash_init, NULL, &flash_data, &ifx_cat1_flash_config,
|
||||
POST_KERNEL, CONFIG_FLASH_INIT_PRIORITY, &ifx_cat1_flash_driver_api);
|
|
@ -35,12 +35,14 @@
|
|||
flash0: flash@10000000 {
|
||||
compatible = "soc-nv-flash";
|
||||
reg = <0x10000000 0x200000>;
|
||||
write-block-size = <4>;
|
||||
write-block-size = <512>;
|
||||
erase-block-size = <512>;
|
||||
};
|
||||
flash1: flash@14000000 {
|
||||
compatible = "soc-nv-flash";
|
||||
reg = <0x14000000 0x8000>;
|
||||
write-block-size = <4>;
|
||||
write-block-size = <512>;
|
||||
erase-block-size = <512>;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
description: Infineon CAT1 flash controller
|
||||
|
||||
compatible: "infineon,cat1-flash-controller"
|
||||
|
||||
include: flash-controller.yaml
|
|
@ -66,4 +66,9 @@ config ABSTRACTION_RTOS_COMPONENT_ZEPHYR
|
|||
help
|
||||
Enable Abstraction RTOS component with Zephyr support
|
||||
|
||||
config USE_INFINEON_FLASH
|
||||
bool
|
||||
help
|
||||
Enable Flash HAL module driver for Infineon devices
|
||||
|
||||
endif # SOC_FAMILY_PSOC6
|
||||
|
|
|
@ -68,6 +68,7 @@ zephyr_library_sources_ifdef(CONFIG_SOC_DIE_PSOC6_04
|
|||
|
||||
# High level interface for interacting with CAT1 hardware
|
||||
zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_ADC ${hal_psoc6_dir}/source/cyhal_adc_sar.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_FLASH ${hal_psoc6_dir}/source/cyhal_flash.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_I2C ${hal_psoc6_dir}/source/cyhal_i2c.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_LPTIMER ${hal_psoc6_dir}/source/cyhal_lptimer.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_PWM ${hal_psoc6_dir}/source/cyhal_pwm.c)
|
||||
|
|
|
@ -35,6 +35,7 @@ zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_SDIO ${pdl_drv_dir}/source/
|
|||
zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_SPI ${pdl_drv_dir}/source/cy_scb_spi.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_TIMER ${pdl_drv_dir}/source/cy_tcpwm_counter.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_UART ${pdl_drv_dir}/source/cy_scb_uart.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_FLASH ${pdl_drv_dir}/source/cy_flash.c)
|
||||
|
||||
if(CONFIG_USE_INFINEON_TRNG)
|
||||
zephyr_library_sources(${pdl_drv_dir}/source/cy_crypto.c)
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
&flash0 {
|
||||
partitions {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "fixed-partitions";
|
||||
|
||||
/* Set 3Kb of storage at the end of the of 2Mb flash 0 */
|
||||
storage_partition: partition@1ff400 {
|
||||
label = "storage";
|
||||
reg = <0x1ff400 DT_SIZE_K(3)>;
|
||||
};
|
||||
};
|
||||
};
|
13
samples/drivers/flash_shell/boards/cy8cproto_063_ble.overlay
Normal file
13
samples/drivers/flash_shell/boards/cy8cproto_063_ble.overlay
Normal file
|
@ -0,0 +1,13 @@
|
|||
&flash0 {
|
||||
partitions {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "fixed-partitions";
|
||||
|
||||
/* Set 3Kb of storage at the end of the of 1Mb flash 0 */
|
||||
storage_partition: partition@ff400 {
|
||||
label = "storage";
|
||||
reg = <0xff400 DT_SIZE_K(3)>;
|
||||
};
|
||||
};
|
||||
};
|
13
samples/subsys/nvs/boards/cy8cproto_062_4343w.overlay
Normal file
13
samples/subsys/nvs/boards/cy8cproto_062_4343w.overlay
Normal file
|
@ -0,0 +1,13 @@
|
|||
&flash0 {
|
||||
partitions {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "fixed-partitions";
|
||||
|
||||
/* Set 3Kb of storage at the end of the of 2Mb flash 0 */
|
||||
storage_partition: partition@1ff400 {
|
||||
label = "storage";
|
||||
reg = <0x1ff400 DT_SIZE_K(3)>;
|
||||
};
|
||||
};
|
||||
};
|
13
samples/subsys/nvs/boards/cy8cproto_063_ble.overlay
Normal file
13
samples/subsys/nvs/boards/cy8cproto_063_ble.overlay
Normal file
|
@ -0,0 +1,13 @@
|
|||
&flash0 {
|
||||
partitions {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "fixed-partitions";
|
||||
|
||||
/* Set 3Kb of storage at the end of the of 1Mb flash 0 */
|
||||
storage_partition: partition@ff400 {
|
||||
label = "storage";
|
||||
reg = <0xff400 DT_SIZE_K(3)>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -0,0 +1,13 @@
|
|||
&flash0 {
|
||||
partitions {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "fixed-partitions";
|
||||
|
||||
/* Set 3Kb of storage at the end of the of 2Mb flash 0 */
|
||||
storage_partition: partition@1ff400 {
|
||||
label = "storage";
|
||||
reg = <0x1ff400 DT_SIZE_K(3)>;
|
||||
};
|
||||
};
|
||||
};
|
13
tests/drivers/flash/common/boards/cy8cproto_063_ble.overlay
Normal file
13
tests/drivers/flash/common/boards/cy8cproto_063_ble.overlay
Normal file
|
@ -0,0 +1,13 @@
|
|||
&flash0 {
|
||||
partitions {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "fixed-partitions";
|
||||
|
||||
/* Set 3Kb of storage at the end of the of 1Mb flash 0 */
|
||||
storage_partition: partition@ff400 {
|
||||
label = "storage";
|
||||
reg = <0xff400 DT_SIZE_K(3)>;
|
||||
};
|
||||
};
|
||||
};
|
Loading…
Reference in a new issue