1 /*
2 * Copyright 2023 NXP
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT nxp_s32_qspi
8
9 #include <zephyr/logging/log.h>
10 LOG_MODULE_REGISTER(nxp_s32_qspi_memc, CONFIG_MEMC_LOG_LEVEL);
11
12 #include <zephyr/drivers/pinctrl.h>
13 #include <zephyr/sys/util.h>
14 #include <zephyr/dt-bindings/qspi/nxp-s32-qspi.h>
15
16 #include <soc.h>
17 #include "memc_nxp_s32_qspi.h"
18
19 /* Mapping between QSPI chip select signals and devicetree chip select identifiers */
20 #define QSPI_PCSFA1 0
21 #define QSPI_PCSFA2 1
22 #define QSPI_PCSFB1 2
23 #define QSPI_PCSFB2 3
24
25 struct memc_nxp_s32_qspi_data {
26 uint8_t instance;
27 };
28
29 struct memc_nxp_s32_qspi_config {
30 QuadSPI_Type *base;
31 const struct pinctrl_dev_config *pincfg;
32
33 const Qspi_Ip_ControllerConfigType *controller_cfg;
34 };
35
get_instance(QuadSPI_Type * base)36 static inline uint8_t get_instance(QuadSPI_Type *base)
37 {
38 QuadSPI_Type *const base_ptrs[QuadSPI_INSTANCE_COUNT] = IP_QuadSPI_BASE_PTRS;
39 uint8_t i;
40
41 for (i = 0; i < QuadSPI_INSTANCE_COUNT; i++) {
42 if (base_ptrs[i] == base) {
43 break;
44 }
45 }
46 __ASSERT_NO_MSG(i < QuadSPI_INSTANCE_COUNT);
47
48 return i;
49 }
50
memc_nxp_s32_qspi_init(const struct device * dev)51 static int memc_nxp_s32_qspi_init(const struct device *dev)
52 {
53 const struct memc_nxp_s32_qspi_config *config = dev->config;
54 struct memc_nxp_s32_qspi_data *data = dev->data;
55 Qspi_Ip_StatusType status;
56
57 data->instance = get_instance(config->base);
58
59 if (pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT)) {
60 return -EIO;
61 }
62
63 status = Qspi_Ip_ControllerInit(data->instance, config->controller_cfg);
64 if (status != STATUS_QSPI_IP_SUCCESS) {
65 LOG_ERR("Fail to initialize QSPI controller %d (%d)",
66 data->instance, status);
67 return -EIO;
68 }
69
70 return 0;
71 }
72
memc_nxp_s32_qspi_get_instance(const struct device * dev)73 uint8_t memc_nxp_s32_qspi_get_instance(const struct device *dev)
74 {
75 struct memc_nxp_s32_qspi_data *data = dev->data;
76
77 return data->instance;
78 }
79
80 #define QSPI_DATA_CFG(n) \
81 IF_ENABLED(FEATURE_QSPI_DDR, ( \
82 .dataRate = _CONCAT(QSPI_IP_DATA_RATE_, \
83 DT_INST_STRING_UPPER_TOKEN(n, data_rate)), \
84 .dataAlign = COND_CODE_1(DT_INST_PROP(n, hold_time_2x), \
85 (QSPI_IP_FLASH_DATA_ALIGN_2X_REFCLK), \
86 (QSPI_IP_FLASH_DATA_ALIGN_REFCLK)), \
87 ))
88
89 #define QSPI_ADDR_CFG(n) \
90 IF_ENABLED(FEATURE_QSPI_ADDR_CFG, ( \
91 .columnAddr = DT_INST_PROP_OR(n, column_space, 0), \
92 .wordAddresable = DT_INST_PROP(n, word_addressable), \
93 ))
94
95 #define QSPI_BYTES_SWAP_ADDR(n) \
96 IF_ENABLED(FEATURE_QSPI_BYTES_SWAP_ADDR, \
97 (.byteSwap = DT_INST_PROP(n, byte_swapping),))
98
99 #define QSPI_SAMPLE_DELAY(n) \
100 COND_CODE_1(DT_INST_PROP(n, sample_delay_half_cycle), \
101 (QSPI_IP_SAMPLE_DELAY_HALFCYCLE_EARLY_DQS), \
102 (QSPI_IP_SAMPLE_DELAY_SAME_DQS))
103
104 #define QSPI_SAMPLE_PHASE(n) \
105 COND_CODE_1(DT_INST_PROP(n, sample_phase_inverted), \
106 (QSPI_IP_SAMPLE_PHASE_INVERTED), \
107 (QSPI_IP_SAMPLE_PHASE_NON_INVERTED))
108
109 #define QSPI_AHB_BUFFERS(n) \
110 { \
111 .masters = DT_INST_PROP(n, ahb_buffers_masters), \
112 .sizes = DT_INST_PROP(n, ahb_buffers_sizes), \
113 .allMasters = (bool)DT_INST_PROP(n, ahb_buffers_all_masters), \
114 }
115
116 #define QSPI_DLL_CFG(n, side, side_upper) \
117 IF_ENABLED(FEATURE_QSPI_HAS_DLL, ( \
118 .dllSettings##side_upper = { \
119 .dllMode = _CONCAT(QSPI_IP_DLL_, \
120 DT_INST_STRING_UPPER_TOKEN(n, side##_dll_mode)), \
121 .freqEnable = DT_INST_PROP(n, side##_dll_freq_enable), \
122 .coarseDelay = DT_INST_PROP(n, side##_dll_coarse_delay), \
123 .fineDelay = DT_INST_PROP(n, side##_dll_fine_delay), \
124 .tapSelect = DT_INST_PROP(n, side##_dll_tap_select), \
125 IF_ENABLED(FEATURE_QSPI_DLL_LOOPCONTROL, ( \
126 .referenceCounter = DT_INST_PROP(n, side##_dll_ref_counter), \
127 .resolution = DT_INST_PROP(n, side##_dll_resolution), \
128 )) \
129 }, \
130 ))
131
132 #define QSPI_READ_MODE(n, side, side_upper) \
133 _CONCAT(QSPI_IP_READ_MODE_, DT_INST_STRING_UPPER_TOKEN(n, side##_rx_clock_source))
134
135 #define QSPI_IDLE_SIGNAL_DRIVE(n, side, side_upper) \
136 IF_ENABLED(FEATURE_QSPI_CONFIGURABLE_ISD, ( \
137 .io2IdleValue##side_upper = (uint8_t)DT_INST_PROP(n, side##_io2_idle_high),\
138 .io3IdleValue##side_upper = (uint8_t)DT_INST_PROP(n, side##_io3_idle_high),\
139 ))
140
141 #define QSPI_PORT_SIZE_FN(node_id, side_upper, port) \
142 COND_CODE_1(IS_EQ(DT_REG_ADDR_RAW(node_id), QSPI_PCSF##side_upper##port), \
143 (COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(node_id), \
144 (.memSize##side_upper##port = DT_PROP(node_id, size) / 8,), \
145 (.memSize##side_upper##port = 0,))), \
146 (EMPTY))
147
148 #define QSPI_PORT_SIZE(n, side_upper) \
149 DT_INST_FOREACH_CHILD_VARGS(n, QSPI_PORT_SIZE_FN, side_upper, 1) \
150 DT_INST_FOREACH_CHILD_VARGS(n, QSPI_PORT_SIZE_FN, side_upper, 2)
151
152 #define QSPI_SIDE_CFG(n, side, side_upper) \
153 QSPI_IDLE_SIGNAL_DRIVE(n, side, side_upper) \
154 QSPI_DLL_CFG(n, side, side_upper) \
155 QSPI_PORT_SIZE(n, side_upper) \
156 .readMode##side_upper = QSPI_READ_MODE(n, side, side_upper),
157
158 #if FEATURE_QSPI_HAS_SFP
159
160 #if QSPI_IP_SFP_ENABLE_MDAD
161 #define SFP_MDAD_NODE(n) DT_INST_CHILD(n, sfp_mdad)
162
163 #define QSPI_SECURE_ATTRIBUTE(node_id) \
164 (DT_PROP(node_id, secure_attribute) == NXP_S32_QSPI_NON_SECURE ? QSPI_IP_SFP_UNSECURE : \
165 (DT_PROP(node_id, secure_attribute) == NXP_S32_QSPI_SECURE ? QSPI_IP_SFP_SECURE : \
166 (DT_PROP(node_id, secure_attribute) == (NXP_S32_QSPI_NON_SECURE | NXP_S32_QSPI_SECURE) ?\
167 QSPI_IP_SFP_BOTH : \
168 QSPI_IP_SFP_RESERVED)))
169
170 #define _QSPI_SFP_MDAD_CFG(node_id, n) \
171 { \
172 .SecureAttribute = QSPI_SECURE_ATTRIBUTE(node_id), \
173 .MaskType = DT_ENUM_IDX(node_id, mask_type), \
174 .Valid = true, \
175 .Mask = DT_PROP(node_id, mask), \
176 .DomainId = DT_PROP(node_id, domain_id), \
177 },
178
179 #define QSPI_SFP_MDAD_CFG(n) \
180 .Tg = { \
181 DT_FOREACH_CHILD_STATUS_OKAY_VARGS(SFP_MDAD_NODE(n), _QSPI_SFP_MDAD_CFG, n)\
182 },
183 #endif /* QSPI_IP_SFP_ENABLE_MDAD */
184
185 #if QSPI_IP_SFP_ENABLE_FRAD
186 #define SFP_FRAD_NODE(n) DT_INST_CHILD(n, sfp_frad)
187
188 #define QSPI_ACP_POLICY(node_id) \
189 (DT_PROP(node_id, master_domain_acp_policy) == NXP_S32_QSPI_SECURE ? \
190 QSPI_IP_SFP_ACP_SECURE :\
191 (DT_PROP(node_id, master_domain_acp_policy) == (NXP_S32_QSPI_NON_SECURE | \
192 NXP_S32_QSPI_PRIVILEGE) ? QSPI_IP_SFP_ACP_PRIVILEGED : \
193 (DT_PROP(node_id, master_domain_acp_policy) == (NXP_S32_QSPI_SECURE | \
194 NXP_S32_QSPI_PRIVILEGE) ? QSPI_IP_SFP_ACP_SECURE_PRIVILEGED :\
195 (DT_PROP(node_id, master_domain_acp_policy) == (NXP_S32_QSPI_NON_SECURE | \
196 NXP_S32_QSPI_SECURE | NXP_S32_QSPI_PRIVILEGE) ? QSPI_IP_SFP_ACP_ALL : \
197 QSPI_IP_SFP_ACP_NONE))))
198
199 #define QSPI_EXCLUSIVE_ACCESS_LOCK(node_id) \
200 (DT_ENUM_IDX(node_id, exclusive_access_lock) == 0 ? QSPI_IP_SFP_EAL_DISABLED : \
201 (DT_ENUM_IDX(node_id, exclusive_access_lock) == 1 ? QSPI_IP_SFP_EAL_OWNER : \
202 QSPI_IP_SFP_EAL_NONE))
203
204 #define _QSPI_SFP_FRAD_CFG(node_id, n) \
205 { \
206 .StartAddress = DT_REG_ADDR(node_id), \
207 .EndAddress = DT_REG_ADDR(node_id) + DT_REG_SIZE(node_id) - 1, \
208 .Valid = true, \
209 .Md0Acp = QSPI_ACP_POLICY(node_id), \
210 .Md1Acp = QSPI_ACP_POLICY(node_id), \
211 .ExclusiveAccessLock = QSPI_EXCLUSIVE_ACCESS_LOCK(node_id), \
212 .ExclusiveAccessOwner = DT_PROP(node_id, exclusive_access_owner), \
213 },
214
215 #define QSPI_SFP_FRAD_CFG(n) \
216 .Frad = { \
217 DT_FOREACH_CHILD_STATUS_OKAY_VARGS(SFP_FRAD_NODE(n), _QSPI_SFP_FRAD_CFG, n)\
218 },
219 #endif /* QSPI_IP_SFP_ENABLE_FRAD */
220
221 #define QSPI_SFP_MASTER_TIMEOUT_CYCLES 0xffff
222
223 #define QSPI_SFP_CFG(n) \
224 IF_ENABLED(QSPI_IP_SFP_ENABLE_GLOBAL, \
225 (.SfpCfg = { \
226 .MasterTimeout = QSPI_SFP_MASTER_TIMEOUT_CYCLES, \
227 IF_ENABLED(QSPI_IP_SFP_ENABLE_MDAD, (QSPI_SFP_MDAD_CFG(n))) \
228 IF_ENABLED(QSPI_IP_SFP_ENABLE_FRAD, (QSPI_SFP_FRAD_CFG(n))) \
229 },))
230
231 #endif /* FEATURE_QSPI_HAS_SFP */
232
233 #define MEMC_NXP_S32_QSPI_CONTROLLER_CONFIG(n) \
234 BUILD_ASSERT(DT_INST_PROP_LEN(n, ahb_buffers_masters) == QSPI_IP_AHB_BUFFERS, \
235 "ahb-buffers-masters must be of size QSPI_IP_AHB_BUFFERS"); \
236 BUILD_ASSERT(DT_INST_PROP_LEN(n, ahb_buffers_sizes) == QSPI_IP_AHB_BUFFERS, \
237 "ahb-buffers-sizes must be of size QSPI_IP_AHB_BUFFERS"); \
238 BUILD_ASSERT( \
239 _CONCAT(FEATURE_QSPI_, DT_INST_STRING_UPPER_TOKEN(n, a_rx_clock_source)) == 1,\
240 "a-rx-clock-source source mode selected is not supported"); \
241 \
242 static const Qspi_Ip_ControllerConfigType \
243 memc_nxp_s32_qspi_controller_cfg_##n = { \
244 .csHoldTime = DT_INST_PROP(n, cs_hold_time), \
245 .csSetupTime = DT_INST_PROP(n, cs_setup_time), \
246 .sampleDelay = QSPI_SAMPLE_DELAY(n), \
247 .samplePhase = QSPI_SAMPLE_PHASE(n), \
248 .ahbConfig = QSPI_AHB_BUFFERS(n), \
249 QSPI_SIDE_CFG(n, a, A) \
250 QSPI_DATA_CFG(n) \
251 QSPI_ADDR_CFG(n) \
252 QSPI_BYTES_SWAP_ADDR(n) \
253 IF_ENABLED(FEATURE_QSPI_HAS_SFP, (QSPI_SFP_CFG(n))) \
254 }
255
256 #define MEMC_NXP_S32_QSPI_INIT_DEVICE(n) \
257 PINCTRL_DT_INST_DEFINE(n); \
258 MEMC_NXP_S32_QSPI_CONTROLLER_CONFIG(n); \
259 static struct memc_nxp_s32_qspi_data memc_nxp_s32_qspi_data_##n; \
260 static const struct memc_nxp_s32_qspi_config memc_nxp_s32_qspi_config_##n = { \
261 .base = (QuadSPI_Type *)DT_INST_REG_ADDR(n), \
262 .controller_cfg = &memc_nxp_s32_qspi_controller_cfg_##n, \
263 .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
264 }; \
265 DEVICE_DT_INST_DEFINE(n, \
266 memc_nxp_s32_qspi_init, \
267 NULL, \
268 &memc_nxp_s32_qspi_data_##n, \
269 &memc_nxp_s32_qspi_config_##n, \
270 POST_KERNEL, \
271 CONFIG_MEMC_INIT_PRIORITY, \
272 NULL);
273
274 DT_INST_FOREACH_STATUS_OKAY(MEMC_NXP_S32_QSPI_INIT_DEVICE)
275