/* * 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 #include #include #include #include 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)