1 /*
2 * Copyright (c) 2022 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #define DT_DRV_COMPAT cdns_qspi_nor
7
8 #include "flash_cadence_qspi_nor_ll.h"
9
10 #include <string.h>
11
12 #include <zephyr/kernel.h>
13 #include <zephyr/device.h>
14 #include <zephyr/drivers/flash.h>
15 #include <zephyr/logging/log.h>
16
17 LOG_MODULE_REGISTER(flash_cadence, CONFIG_FLASH_LOG_LEVEL);
18
19 struct flash_cad_priv {
20 DEVICE_MMIO_NAMED_RAM(qspi_reg);
21 DEVICE_MMIO_NAMED_RAM(qspi_data);
22 struct cad_qspi_params params;
23 };
24
25 struct flash_cad_config {
26 DEVICE_MMIO_NAMED_ROM(qspi_reg);
27 DEVICE_MMIO_NAMED_ROM(qspi_data);
28 };
29
30 static const struct flash_parameters flash_cad_parameters = {
31 .write_block_size = QSPI_BYTES_PER_DEV,
32 .erase_value = 0xff,
33 };
34
35 #define DEV_DATA(dev) ((struct flash_cad_priv *)((dev)->data))
36 #define DEV_CFG(dev) ((struct flash_cad_config *)((dev)->config))
37
flash_cad_read(const struct device * dev,off_t offset,void * data,size_t len)38 static int flash_cad_read(const struct device *dev, off_t offset,
39 void *data, size_t len)
40 {
41 struct flash_cad_priv *priv = dev->data;
42 struct cad_qspi_params *cad_params = &priv->params;
43 int rc;
44
45 if ((data == NULL) || (len == 0)) {
46 LOG_ERR("Invalid input parameter for QSPI Read!");
47 return -EINVAL;
48 }
49
50 rc = cad_qspi_read(cad_params, data, (uint32_t)offset, len);
51
52 if (rc < 0) {
53 LOG_ERR("Cadence QSPI Flash Read Failed");
54 return rc;
55 }
56
57 return 0;
58 }
59
flash_cad_erase(const struct device * dev,off_t offset,size_t len)60 static int flash_cad_erase(const struct device *dev, off_t offset,
61 size_t len)
62 {
63 struct flash_cad_priv *priv = dev->data;
64 struct cad_qspi_params *cad_params = &priv->params;
65 int rc;
66
67 if (len == 0) {
68 LOG_ERR("Invalid input parameter for QSPI Erase!");
69 return -EINVAL;
70 }
71
72 rc = cad_qspi_erase(cad_params, (uint32_t)offset, len);
73
74 if (rc < 0) {
75 LOG_ERR("Cadence QSPI Flash Erase Failed!");
76 return rc;
77 }
78
79 return 0;
80 }
81
flash_cad_write(const struct device * dev,off_t offset,const void * data,size_t len)82 static int flash_cad_write(const struct device *dev, off_t offset,
83 const void *data, size_t len)
84 {
85 struct flash_cad_priv *priv = dev->data;
86 struct cad_qspi_params *cad_params = &priv->params;
87 int rc;
88
89 if ((data == NULL) || (len == 0)) {
90 LOG_ERR("Invalid input parameter for QSPI Write!");
91 return -EINVAL;
92 }
93
94 rc = cad_qspi_write(cad_params, (void *)data, (uint32_t)offset, len);
95
96 if (rc < 0) {
97 LOG_ERR("Cadence QSPI Flash Write Failed!");
98 return rc;
99 }
100
101 return 0;
102 }
103
104 static const struct flash_parameters *
flash_cad_get_parameters(const struct device * dev)105 flash_cad_get_parameters(const struct device *dev)
106 {
107 ARG_UNUSED(dev);
108
109 return &flash_cad_parameters;
110 }
111
112 static const struct flash_driver_api flash_cad_api = {
113 .erase = flash_cad_erase,
114 .write = flash_cad_write,
115 .read = flash_cad_read,
116 .get_parameters = flash_cad_get_parameters,
117 };
118
flash_cad_init(const struct device * dev)119 static int flash_cad_init(const struct device *dev)
120 {
121 struct flash_cad_priv *priv = dev->data;
122 struct cad_qspi_params *cad_params = &priv->params;
123 int rc;
124
125 DEVICE_MMIO_NAMED_MAP(dev, qspi_reg, K_MEM_CACHE_NONE);
126 DEVICE_MMIO_NAMED_MAP(dev, qspi_data, K_MEM_CACHE_NONE);
127
128 cad_params->reg_base = DEVICE_MMIO_NAMED_GET(dev, qspi_reg);
129 cad_params->data_base = DEVICE_MMIO_NAMED_GET(dev, qspi_data);
130
131 rc = cad_qspi_init(cad_params, QSPI_CONFIG_CPHA,
132 QSPI_CONFIG_CPOL, QSPI_CONFIG_CSDA,
133 QSPI_CONFIG_CSDADS, QSPI_CONFIG_CSEOT,
134 QSPI_CONFIG_CSSOT, 0);
135
136 if (rc < 0) {
137 LOG_ERR("Cadence QSPI Flash Init Failed");
138 return rc;
139 }
140
141 return 0;
142 }
143
144 #define CREATE_FLASH_CADENCE_QSPI_DEVICE(inst) \
145 static struct flash_cad_priv flash_cad_priv_##inst = { \
146 .params = { \
147 .clk_rate = DT_INST_PROP(inst, clock_frequency),\
148 .data_size = DT_INST_REG_SIZE_BY_IDX(inst, 1), \
149 }, \
150 }; \
151 \
152 static struct flash_cad_config flash_cad_config_##inst = { \
153 DEVICE_MMIO_NAMED_ROM_INIT_BY_NAME( \
154 qspi_reg, DT_DRV_INST(inst)), \
155 DEVICE_MMIO_NAMED_ROM_INIT_BY_NAME( \
156 qspi_data, DT_DRV_INST(inst)), \
157 }; \
158 \
159 DEVICE_DT_INST_DEFINE(inst, \
160 flash_cad_init, \
161 NULL, \
162 &flash_cad_priv_##inst, \
163 &flash_cad_config_##inst, \
164 POST_KERNEL, \
165 CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \
166 &flash_cad_api);
167
168 DT_INST_FOREACH_STATUS_OKAY(CREATE_FLASH_CADENCE_QSPI_DEVICE)
169