Zephyr Project API 4.4.99
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
util.h
Go to the documentation of this file.
1/*
2 * Copyright 2024,2026 NXP
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
15
16#ifndef ZEPHYR_INCLUDE_DRIVERS_FIRMWARE_SCMI_UTIL_H_
17#define ZEPHYR_INCLUDE_DRIVERS_FIRMWARE_SCMI_UTIL_H_
18
25
37#define SCMI_PROTOCOL_NAME(proto) CONCAT(scmi_protocol_, proto)
38
39#ifdef CONFIG_ARM_SCMI_MAILBOX_TRANSPORT
43#define DT_SCMI_TRANSPORT_COMPATIBLE arm_scmi
44#elif CONFIG_ARM_SCMI_SMC_TRANSPORT
48#define DT_SCMI_TRANSPORT_COMPATIBLE arm_scmi_smc
49#else
50#error "Transport needs to define COMPATIBLE macro"
51#endif
52
64#define DT_SCMI_TRANSPORT_PROTO_IS_BASE(node_id) \
65 DT_NODE_HAS_COMPAT(node_id, DT_SCMI_TRANSPORT_COMPATIBLE)
66
77#define DT_SCMI_TRANSPORT_PROTOCOL_ID(node_id) \
78 COND_CODE_1(DT_SCMI_TRANSPORT_PROTO_IS_BASE(node_id), \
79 (SCMI_PROTOCOL_BASE), \
80 (DT_REG_ADDR_RAW(node_id)))
81
82#ifdef CONFIG_ARM_SCMI_TRANSPORT_HAS_STATIC_CHANNELS
83
84#ifdef CONFIG_ARM_SCMI_MAILBOX_TRANSPORT
98#define DT_SCMI_TRANSPORT_PROTO_HAS_CHAN(node_id, idx)\
99 DT_PROP_HAS_IDX(node_id, shmem, idx)
100#elif CONFIG_ARM_SCMI_SMC_TRANSPORT
111#define DT_SCMI_TRANSPORT_PROTO_HAS_CHAN(node_id, idx) \
112 COND_CODE_1(DT_SCMI_TRANSPORT_PROTO_IS_BASE(node_id), \
113 (DT_PROP_HAS_IDX(node_id, shmem, idx)), \
114 (0))
115#else
116#error "Transport with static channels needs to define HAS_CHAN macro"
117#endif
118
120/* builds the symbol name of the static channel for a (proto, idx) pair */
121#define SCMI_TRANSPORT_CHAN_NAME(proto, idx) CONCAT(scmi_channel_, proto, _, idx)
123
125
126/*
127 * Declare a TX SCMI channel.
128 *
129 * Given a @p node_id for a protocol, this macro declares the SCMI
130 * TX channel statically bound to said protocol via the "extern"
131 * qualifier. This is useful when the transport layer driver
132 * supports static channels since all channel structures are
133 * defined inside the transport layer driver. Internal helper used
134 * by DT_SCMI_TRANSPORT_CHANNELS_DECLARE(); not meant to be used directly.
135 *
136 * @param node_id Protocol node identifier
137 */
138#define DT_SCMI_TRANSPORT_TX_CHAN_DECLARE(node_id) \
139 COND_CODE_1(DT_SCMI_TRANSPORT_PROTO_HAS_CHAN(node_id, 0), \
140 (extern struct scmi_channel \
141 SCMI_TRANSPORT_CHAN_NAME( \
142 DT_SCMI_TRANSPORT_PROTOCOL_ID(node_id), 0);), \
143 (extern struct scmi_channel \
144 SCMI_TRANSPORT_CHAN_NAME(SCMI_PROTOCOL_BASE, 0);)) \
145
146
169#define DT_SCMI_TRANSPORT_RX_CHAN_DECLARE_BASE_RAW(node_id) \
170 COND_CODE_1(DT_SCMI_TRANSPORT_PROTO_HAS_CHAN(node_id, 1), \
171 (extern struct scmi_channel \
172 SCMI_TRANSPORT_CHAN_NAME(SCMI_PROTOCOL_BASE, 1);), \
173 ())
174
175#define DT_SCMI_TRANSPORT_RX_CHAN_DECLARE_BASE(node_id) \
176 COND_CODE_1(DT_SCMI_TRANSPORT_PROTO_IS_BASE(node_id), \
177 (DT_SCMI_TRANSPORT_RX_CHAN_DECLARE_BASE_RAW(node_id)), \
178 (DT_SCMI_TRANSPORT_RX_CHAN_DECLARE_BASE_RAW(DT_PARENT(node_id)))) \
179
180#define DT_SCMI_TRANSPORT_RX_CHAN_DECLARE(node_id) \
181 COND_CODE_1(DT_SCMI_TRANSPORT_PROTO_HAS_CHAN(node_id, 1), \
182 (extern struct scmi_channel \
183 SCMI_TRANSPORT_CHAN_NAME(DT_REG_ADDR_RAW(node_id), 1);), \
184 (DT_SCMI_TRANSPORT_RX_CHAN_DECLARE_BASE(node_id)))
185
195#define DT_SCMI_TRANSPORT_CHANNELS_DECLARE(node_id) \
196 DT_SCMI_TRANSPORT_TX_CHAN_DECLARE(node_id) \
197 DT_SCMI_TRANSPORT_RX_CHAN_DECLARE(node_id) \
198
207#define DT_INST_SCMI_TRANSPORT_CHANNELS_DECLARE(inst) \
208 DT_SCMI_TRANSPORT_CHANNELS_DECLARE(DT_INST(inst, DT_DRV_COMPAT))
209
222#define DT_SCMI_TRANSPORT_TX_CHAN(node_id) \
223 COND_CODE_1(DT_SCMI_TRANSPORT_PROTO_HAS_CHAN(node_id, 0), \
224 (&SCMI_TRANSPORT_CHAN_NAME( \
225 DT_SCMI_TRANSPORT_PROTOCOL_ID(node_id), 0)), \
226 (&SCMI_TRANSPORT_CHAN_NAME(SCMI_PROTOCOL_BASE, 0)))
227
240#define DT_SCMI_TRANSPORT_RX_CHAN_BASE_RAW(node_id) \
241 COND_CODE_1(DT_SCMI_TRANSPORT_PROTO_HAS_CHAN(node_id, 1), \
242 (&SCMI_TRANSPORT_CHAN_NAME(SCMI_PROTOCOL_BASE, 1)), \
243 (NULL))
244
245#define DT_SCMI_TRANSPORT_RX_CHAN_BASE(node_id) \
246 COND_CODE_1(DT_SCMI_TRANSPORT_PROTO_IS_BASE(node_id), \
247 (DT_SCMI_TRANSPORT_RX_CHAN_BASE_RAW(node_id)), \
248 (DT_SCMI_TRANSPORT_RX_CHAN_BASE_RAW(DT_PARENT(node_id))))
249
250#define DT_SCMI_TRANSPORT_RX_CHAN(node_id) \
251 COND_CODE_1(DT_SCMI_TRANSPORT_PROTO_HAS_CHAN(node_id, 1), \
252 (&SCMI_TRANSPORT_CHAN_NAME(DT_REG_ADDR_RAW(node_id), 1)), \
253 (DT_SCMI_TRANSPORT_RX_CHAN_BASE(node_id)))
254
255
269#define DT_SCMI_TRANSPORT_CHAN_DEFINE(node_id, idx, proto, pdata) \
270 struct scmi_channel SCMI_TRANSPORT_CHAN_NAME(proto, idx) = \
271 { \
272 .data = pdata, \
273 }
274
276
277/*
278 * Define an SCMI protocol's data.
279 *
280 * Each SCMI protocol is identified by a struct scmi_protocol
281 * placed in a linker section called scmi_protocol. Each protocol
282 * driver is required to use this macro for "registration". Using
283 * this macro directly is highly discouraged and users should opt
284 * for macros such as DT_SCMI_PROTOCOL_DEFINE_NODEV() or
285 * DT_SCMI_PROTOCOL_DEFINE(), which also takes care of the static
286 * channel declaration (if applicable).
287 *
288 * @param node_id Protocol node identifier
289 * @param proto Protocol ID in decimal format
290 * @param pdata Protocol private data
291 * @param version_val Protocol version supported by the driver
292 * @param pevents Protocol registered events
293 */
294#define DT_SCMI_PROTOCOL_DATA_DEFINE(node_id, proto, pdata, version_val, pevents) \
295 STRUCT_SECTION_ITERABLE(scmi_protocol, SCMI_PROTOCOL_NAME(proto)) = \
296 { \
297 .id = proto, \
298 .tx = DT_SCMI_TRANSPORT_TX_CHAN(node_id), \
299 .rx = DT_SCMI_TRANSPORT_RX_CHAN(node_id), \
300 .data = pdata, \
301 .version = version_val, \
302 .events = pevents \
303 }
305
306#else /* CONFIG_ARM_SCMI_TRANSPORT_HAS_STATIC_CHANNELS */
307
309/* no-op variant used when the transport does not support static channels */
310#define DT_SCMI_TRANSPORT_CHANNELS_DECLARE(node_id)
311
312/* variant used when the transport does not support static channels */
313#define DT_SCMI_PROTOCOL_DATA_DEFINE(node_id, proto, pdata) \
314 STRUCT_SECTION_ITERABLE(scmi_protocol, SCMI_PROTOCOL_NAME(proto)) = \
315 { \
316 .id = proto, \
317 .data = pdata, \
318 }
320
321#endif /* CONFIG_ARM_SCMI_TRANSPORT_HAS_STATIC_CHANNELS */
322
335#define DT_INST_SCMI_TRANSPORT_DEFINE(inst, pm, data, config, level, prio, api) \
336 DEVICE_DT_INST_DEFINE(inst, &scmi_core_transport_init, \
337 pm, data, config, level, prio, api)
338
366#define DT_SCMI_PROTOCOL_DEFINE(node_id, init_fn, pm, data, config, \
367 level, prio, api, version_val, events) \
368 DT_SCMI_TRANSPORT_CHANNELS_DECLARE(node_id) \
369 DT_SCMI_PROTOCOL_DATA_DEFINE(node_id, \
370 DT_SCMI_TRANSPORT_PROTOCOL_ID(node_id), \
371 data, version_val, events); \
372 DEVICE_DT_DEFINE(node_id, init_fn, pm, \
373 &SCMI_PROTOCOL_NAME( \
374 DT_SCMI_TRANSPORT_PROTOCOL_ID(node_id)), \
375 config, level, prio, api)
376
391#define DT_INST_SCMI_PROTOCOL_DEFINE(inst, init_fn, pm, data, config, \
392 level, prio, api, version, events) \
393 DT_SCMI_PROTOCOL_DEFINE(DT_INST(inst, DT_DRV_COMPAT), init_fn, pm, \
394 data, config, level, prio, api, version, events)
395
408#define DT_SCMI_PROTOCOL_DEFINE_NODEV(node_id, data, version, events) \
409 DT_SCMI_TRANSPORT_CHANNELS_DECLARE(node_id) \
410 DT_SCMI_PROTOCOL_DATA_DEFINE(node_id, \
411 DT_SCMI_TRANSPORT_PROTOCOL_ID(node_id), \
412 data, version, events)
413
428#define SCMI_FIELD_MAKE(x, mask, shift)\
429 (((uint32_t)(x) & (mask)) << (shift))
430
439#define SCMI_PROTOCOL_BASE 16
440#define SCMI_PROTOCOL_POWER_DOMAIN 17
441#define SCMI_PROTOCOL_SYSTEM 18
442#define SCMI_PROTOCOL_PERF 19
443#define SCMI_PROTOCOL_CLOCK 20
444#define SCMI_PROTOCOL_SENSOR 21
445#define SCMI_PROTOCOL_RESET_DOMAIN 22
446#define SCMI_PROTOCOL_VOLTAGE_DOMAIN 23
447#define SCMI_PROTOCOL_PCAP_MONITOR 24
448#define SCMI_PROTOCOL_PINCTRL 25
449
453
454#endif /* ZEPHYR_INCLUDE_DRIVERS_FIRMWARE_SCMI_UTIL_H_ */