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