forked from zephyrproject-rtos/zephyr
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
drivers: flash: Add Cadence QSPI NOR Flash Driver
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
1 parent
927f82b
commit c3dd728
Showing
6 changed files
with
1,356 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
Oops, something went wrong.