Skip to content

Commit

Permalink
drivers: flash: Add Cadence QSPI NOR Flash Driver
Browse files Browse the repository at this point in the history
This patch is to enable new driver, Cadence QSPI NOR
flash for Intel SoC FPGA Agilex Family

Signed-off-by: Boon Khai Ng <[email protected]>
  • Loading branch information
ngboonkhai authored and nashif committed Sep 1, 2022
1 parent 927f82b commit c3dd728
Show file tree
Hide file tree
Showing 6 changed files with 1,356 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/flash/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ zephyr_library_sources_ifdef(CONFIG_FLASH_MCUX_FLEXSPI_NOR flash_mcux_flexspi_no
zephyr_library_sources_ifdef(CONFIG_FLASH_MCUX_FLEXSPI_HYPERFLASH flash_mcux_flexspi_hyperflash.c)
zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_ESP32 flash_esp32.c)
zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_SMARTBOND flash_smartbond.c)
zephyr_library_sources_ifdef(CONFIG_FLASH_CAD_QSPI_NOR flash_cadence_qspi_nor.c flash_cadence_qspi_nor_ll.c)

if(CONFIG_FLASH_MCUX_FLEXSPI_XIP)
dt_chosen(chosen_flash PROPERTY "zephyr,flash")
Expand Down
2 changes: 2 additions & 0 deletions drivers/flash/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,6 @@ source "drivers/flash/Kconfig.nordic_qspi_nor"

source "drivers/flash/Kconfig.smartbond"

source "drivers/flash/Kconfig.cadence_qspi_nor"

endif # FLASH
46 changes: 46 additions & 0 deletions drivers/flash/Kconfig.cadence_qspi_nor
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Copyright (c) 2022 Intel Corporation.
# SPDX-License-Identifier: Apache-2.0

config FLASH_CAD_QSPI_NOR
bool "Cadence Quad SPI Flash driver"
default y
depends on DT_HAS_CDNS_QSPI_NOR_ENABLED
select FLASH_HAS_PAGE_LAYOUT
select FLASH_HAS_DRIVER_ENABLED
help
Enable Cadence QSPI-NOR support.

if FLASH_CAD_QSPI_NOR

config CAD_QSPI_MICRON_N25Q_SUPPORT
bool "Cadence Quad SPI Micron N25Q Support"
default y
help
Enable Micron N25Q Support.

config CAD_QSPI_NOR_SUBSECTOR_SIZE
hex "Cadence Quad SPI subsector size"
default 0x1000
help
Set the Cadence Quad SPI subsector size.

config QSPI_ADDR_BYTES
int "Access QSPI address memory size in bytes"
default 2
help
Set the address memory size in bytes when
accessing QSPI.

config QSPI_BYTES_PER_DEV
int "Set QSPI to read / write how many bytes per device"
default 256
help
Set the size for a QSPI to read / write per device.

config QSPI_BYTES_PER_BLOCK
int "Set QSPI to read / write how many bytes per block"
default 16
help
Set the size for a QSPI to read / write per block.

endif # FLASH_CAD_QSPI_NOR
168 changes: 168 additions & 0 deletions drivers/flash/flash_cadence_qspi_nor.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/*
* Copyright (c) 2022 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT cdns_qspi_nor

#include "flash_cadence_qspi_nor_ll.h"

#include <string.h>

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/flash.h>
#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(flash_cadence, CONFIG_FLASH_LOG_LEVEL);

struct flash_cad_priv {
DEVICE_MMIO_NAMED_RAM(qspi_reg);
DEVICE_MMIO_NAMED_RAM(qspi_data);
struct cad_qspi_params params;
};

struct flash_cad_config {
DEVICE_MMIO_NAMED_ROM(qspi_reg);
DEVICE_MMIO_NAMED_ROM(qspi_data);
};

static const struct flash_parameters flash_cad_parameters = {
.write_block_size = QSPI_BYTES_PER_DEV,
.erase_value = 0xff,
};

#define DEV_DATA(dev) ((struct flash_cad_priv *)((dev)->data))
#define DEV_CFG(dev) ((struct flash_cad_config *)((dev)->config))

static int flash_cad_read(const struct device *dev, off_t offset,
void *data, size_t len)
{
struct flash_cad_priv *priv = dev->data;
struct cad_qspi_params *cad_params = &priv->params;
int rc;

if ((data == NULL) || (len == 0)) {
LOG_ERR("Invalid input parameter for QSPI Read!");
return -EINVAL;
}

rc = cad_qspi_read(cad_params, data, (uint32_t)offset, len);

if (rc < 0) {
LOG_ERR("Cadence QSPI Flash Read Failed");
return rc;
}

return 0;
}

static int flash_cad_erase(const struct device *dev, off_t offset,
size_t len)
{
struct flash_cad_priv *priv = dev->data;
struct cad_qspi_params *cad_params = &priv->params;
int rc;

if (len == 0) {
LOG_ERR("Invalid input parameter for QSPI Erase!");
return -EINVAL;
}

rc = cad_qspi_erase(cad_params, (uint32_t)offset, len);

if (rc < 0) {
LOG_ERR("Cadence QSPI Flash Erase Failed!");
return rc;
}

return 0;
}

static int flash_cad_write(const struct device *dev, off_t offset,
const void *data, size_t len)
{
struct flash_cad_priv *priv = dev->data;
struct cad_qspi_params *cad_params = &priv->params;
int rc;

if ((data == NULL) || (len == 0)) {
LOG_ERR("Invalid input parameter for QSPI Write!");
return -EINVAL;
}

rc = cad_qspi_write(cad_params, (void *)data, (uint32_t)offset, len);

if (rc < 0) {
LOG_ERR("Cadence QSPI Flash Write Failed!");
return rc;
}

return 0;
}

static const struct flash_parameters *
flash_cad_get_parameters(const struct device *dev)
{
ARG_UNUSED(dev);

return &flash_cad_parameters;
}

static const struct flash_driver_api flash_cad_api = {
.erase = flash_cad_erase,
.write = flash_cad_write,
.read = flash_cad_read,
.get_parameters = flash_cad_get_parameters,
};

static int flash_cad_init(const struct device *dev)
{
struct flash_cad_priv *priv = dev->data;
struct cad_qspi_params *cad_params = &priv->params;
int rc;

DEVICE_MMIO_NAMED_MAP(dev, qspi_reg, K_MEM_CACHE_NONE);
DEVICE_MMIO_NAMED_MAP(dev, qspi_data, K_MEM_CACHE_NONE);

cad_params->reg_base = DEVICE_MMIO_NAMED_GET(dev, qspi_reg);
cad_params->data_base = DEVICE_MMIO_NAMED_GET(dev, qspi_data);

rc = cad_qspi_init(cad_params, QSPI_CONFIG_CPHA,
QSPI_CONFIG_CPOL, QSPI_CONFIG_CSDA,
QSPI_CONFIG_CSDADS, QSPI_CONFIG_CSEOT,
QSPI_CONFIG_CSSOT, 0);

if (rc < 0) {
LOG_ERR("Cadence QSPI Flash Init Failed");
return rc;
}

return 0;
}

#define CREATE_FLASH_CADENCE_QSPI_DEVICE(inst) \
static struct flash_cad_priv flash_cad_priv_##inst = { \
.params = { \
.clk_rate = DT_INST_PROP(inst, clock_frequency),\
.data_size = DT_INST_REG_SIZE_BY_IDX(inst, 1), \
}, \
}; \
\
static struct flash_cad_config flash_cad_config_##inst = { \
DEVICE_MMIO_NAMED_ROM_INIT_BY_NAME( \
qspi_reg, DT_DRV_INST(inst)), \
DEVICE_MMIO_NAMED_ROM_INIT_BY_NAME( \
qspi_data, DT_DRV_INST(inst)), \
}; \
\
DEVICE_DT_INST_DEFINE(inst, \
flash_cad_init, \
NULL, \
&flash_cad_priv_##inst, \
&flash_cad_config_##inst, \
POST_KERNEL, \
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \
&flash_cad_api);

DT_INST_FOREACH_STATUS_OKAY(CREATE_FLASH_CADENCE_QSPI_DEVICE)
Loading

0 comments on commit c3dd728

Please sign in to comment.