Zephyr API Documentation 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 NXP
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
15
16#ifndef _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_UTIL_H_
17#define _INCLUDE_ZEPHYR_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
109#define DT_SCMI_TRANSPORT_PROTO_HAS_CHAN(node_id, idx) 0
110#else
111#error "Transport with static channels needs to define HAS_CHAN macro"
112#endif
113
115/* builds the symbol name of the static channel for a (proto, idx) pair */
116#define SCMI_TRANSPORT_CHAN_NAME(proto, idx) CONCAT(scmi_channel_, proto, _, idx)
118
120
121/*
122 * Declare a TX SCMI channel.
123 *
124 * Given a node_id for a protocol, this macro declares the SCMI
125 * TX channel statically bound to said protocol via the "extern"
126 * qualifier. This is useful when the transport layer driver
127 * supports static channels since all channel structures are
128 * defined inside the transport layer driver. Internal helper used
129 * by DT_SCMI_TRANSPORT_CHANNELS_DECLARE(); not meant to be used directly.
130 */
131#define DT_SCMI_TRANSPORT_TX_CHAN_DECLARE(node_id) \
132 COND_CODE_1(DT_SCMI_TRANSPORT_PROTO_HAS_CHAN(node_id, 0), \
133 (extern struct scmi_channel \
134 SCMI_TRANSPORT_CHAN_NAME( \
135 DT_SCMI_TRANSPORT_PROTOCOL_ID(node_id), 0);), \
136 (extern struct scmi_channel \
137 SCMI_TRANSPORT_CHAN_NAME(SCMI_PROTOCOL_BASE, 0);)) \
138
139
152#define DT_SCMI_TRANSPORT_CHANNELS_DECLARE(node_id) \
153 DT_SCMI_TRANSPORT_TX_CHAN_DECLARE(node_id) \
154
163#define DT_INST_SCMI_TRANSPORT_CHANNELS_DECLARE(inst) \
164 DT_SCMI_TRANSPORT_CHANNELS_DECLARE(DT_INST(inst, DT_DRV_COMPAT))
165
178#define DT_SCMI_TRANSPORT_TX_CHAN(node_id) \
179 COND_CODE_1(DT_SCMI_TRANSPORT_PROTO_HAS_CHAN(node_id, 0), \
180 (&SCMI_TRANSPORT_CHAN_NAME( \
181 DT_SCMI_TRANSPORT_PROTOCOL_ID(node_id), 0)), \
182 (&SCMI_TRANSPORT_CHAN_NAME(SCMI_PROTOCOL_BASE, 0)))
183
197#define DT_SCMI_TRANSPORT_CHAN_DEFINE(node_id, idx, proto, pdata) \
198 struct scmi_channel SCMI_TRANSPORT_CHAN_NAME(proto, idx) = \
199 { \
200 .data = pdata, \
201 }
202
204
205/*
206 * Define an SCMI protocol's data.
207 *
208 * Each SCMI protocol is identified by a struct scmi_protocol
209 * placed in a linker section called scmi_protocol. Each protocol
210 * driver is required to use this macro for "registration". Using
211 * this macro directly is highly discouraged and users should opt
212 * for macros such as DT_SCMI_PROTOCOL_DEFINE_NODEV() or
213 * DT_SCMI_PROTOCOL_DEFINE(), which also takes care of the static
214 * channel declaration (if applicable).
215 *
216 * node_id - protocol node identifier
217 * proto - protocol ID in decimal format
218 * pdata - protocol private data
219 * version_val - protocol version supported by the driver
220 */
221#define DT_SCMI_PROTOCOL_DATA_DEFINE(node_id, proto, pdata, version_val) \
222 STRUCT_SECTION_ITERABLE(scmi_protocol, SCMI_PROTOCOL_NAME(proto)) = \
223 { \
224 .id = proto, \
225 .tx = DT_SCMI_TRANSPORT_TX_CHAN(node_id), \
226 .data = pdata, \
227 .version = version_val \
228 }
230
231#else /* CONFIG_ARM_SCMI_TRANSPORT_HAS_STATIC_CHANNELS */
232
234/* no-op variant used when the transport does not support static channels */
235#define DT_SCMI_TRANSPORT_CHANNELS_DECLARE(node_id)
236
237/* variant used when the transport does not support static channels */
238#define DT_SCMI_PROTOCOL_DATA_DEFINE(node_id, proto, pdata) \
239 STRUCT_SECTION_ITERABLE(scmi_protocol, SCMI_PROTOCOL_NAME(proto)) = \
240 { \
241 .id = proto, \
242 .data = pdata, \
243 }
245
246#endif /* CONFIG_ARM_SCMI_TRANSPORT_HAS_STATIC_CHANNELS */
247
260#define DT_INST_SCMI_TRANSPORT_DEFINE(inst, pm, data, config, level, prio, api) \
261 DEVICE_DT_INST_DEFINE(inst, &scmi_core_transport_init, \
262 pm, data, config, level, prio, api)
263
291#define DT_SCMI_PROTOCOL_DEFINE(node_id, init_fn, pm, data, config, \
292 level, prio, api, version_val) \
293 DT_SCMI_TRANSPORT_CHANNELS_DECLARE(node_id) \
294 DT_SCMI_PROTOCOL_DATA_DEFINE(node_id, \
295 DT_SCMI_TRANSPORT_PROTOCOL_ID(node_id), \
296 data, version_val); \
297 DEVICE_DT_DEFINE(node_id, init_fn, pm, \
298 &SCMI_PROTOCOL_NAME( \
299 DT_SCMI_TRANSPORT_PROTOCOL_ID(node_id)), \
300 config, level, prio, api)
301
316#define DT_INST_SCMI_PROTOCOL_DEFINE(inst, init_fn, pm, data, config, \
317 level, prio, api, version) \
318 DT_SCMI_PROTOCOL_DEFINE(DT_INST(inst, DT_DRV_COMPAT), init_fn, pm, \
319 data, config, level, prio, api, version)
320
333#define DT_SCMI_PROTOCOL_DEFINE_NODEV(node_id, data, version) \
334 DT_SCMI_TRANSPORT_CHANNELS_DECLARE(node_id) \
335 DT_SCMI_PROTOCOL_DATA_DEFINE(node_id, \
336 DT_SCMI_TRANSPORT_PROTOCOL_ID(node_id), \
337 data, version)
338
353#define SCMI_FIELD_MAKE(x, mask, shift)\
354 (((uint32_t)(x) & (mask)) << (shift))
355
364#define SCMI_PROTOCOL_BASE 16
365#define SCMI_PROTOCOL_POWER_DOMAIN 17
366#define SCMI_PROTOCOL_SYSTEM 18
367#define SCMI_PROTOCOL_PERF 19
368#define SCMI_PROTOCOL_CLOCK 20
369#define SCMI_PROTOCOL_SENSOR 21
370#define SCMI_PROTOCOL_RESET_DOMAIN 22
371#define SCMI_PROTOCOL_VOLTAGE_DOMAIN 23
372#define SCMI_PROTOCOL_PCAP_MONITOR 24
373#define SCMI_PROTOCOL_PINCTRL 25
374
378
379#endif /* _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_UTIL_H_ */