1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * Description:
8  *      System Control and Management Interface (SCMI) support.
9  */
10 
11 #ifndef INTERNAL_SCMI_SENSOR_H
12 #define INTERNAL_SCMI_SENSOR_H
13 
14 #include <stdint.h>
15 #ifdef BUILD_HAS_SCMI_SENSOR_V2
16 #    include <mod_sensor.h>
17 
18 #    include <fwk_id.h>
19 #    include <fwk_macros.h>
20 
21 #    include <stddef.h>
22 #    include <stdint.h>
23 #endif
24 
25 /*!
26  * \addtogroup GroupModules Modules
27  * \{
28  */
29 
30 /*!
31  * \defgroup GroupSCMI_SENSOR SCMI Sensor Management Protocol
32  * \{
33  */
34 #ifdef BUILD_HAS_SCMI_SENSOR_V2
35 #    define SCMI_PROTOCOL_VERSION_SENSOR UINT32_C(0x20000)
36 #else
37 #    define SCMI_PROTOCOL_VERSION_SENSOR UINT32_C(0x10000)
38 #endif
39 
40 /*
41  * PROTOCOL_ATTRIBUTES
42  */
43 
44 struct scmi_sensor_protocol_attributes_p2a {
45     int32_t status;
46     uint32_t attributes;
47     uint32_t sensor_reg_address_low;
48     uint32_t sensor_reg_address_high;
49     uint32_t sensor_reg_len;
50 };
51 
52 /*
53  * SENSOR_READING_GET
54  */
55 
56 #define SCMI_SENSOR_PROTOCOL_READING_GET_ASYNC_FLAG_MASK (1U << 0)
57 
58 struct scmi_sensor_trip_point_notify_a2p {
59     uint32_t sensor_id;
60     uint32_t flags;
61 };
62 
63 struct scmi_sensor_trip_point_notify_p2a {
64     int32_t status;
65 };
66 
67 struct scmi_sensor_trip_point_config_a2p {
68     uint32_t sensor_id;
69     uint32_t flags;
70     uint32_t sensor_value_low;
71     uint32_t sensor_value_high;
72 };
73 
74 struct scmi_sensor_trip_point_config_p2a {
75     int32_t status;
76 };
77 
78 struct scmi_sensor_protocol_reading_get_a2p {
79     uint32_t sensor_id;
80     uint32_t flags;
81 };
82 #ifdef BUILD_HAS_SCMI_SENSOR_V2
83 struct scmi_sensor_protocol_reading_get_data {
84     int32_t sensor_value_low;
85     int32_t sensor_value_high;
86     uint32_t timestamp_low;
87     uint32_t timestamp_high;
88 };
89 #endif
90 
91 struct scmi_sensor_protocol_reading_get_p2a {
92     int32_t status;
93 #ifdef BUILD_HAS_SCMI_SENSOR_V2
94     struct scmi_sensor_protocol_reading_get_data data[];
95 #else
96     uint32_t sensor_value_low;
97     uint32_t sensor_value_high;
98 #endif
99 };
100 
101 /*
102  * SENSOR TRIP POINT EVENT
103  */
104 struct scmi_sensor_trip_point_event_p2a {
105     uint32_t agent_id;
106     uint32_t sensor_id;
107     uint32_t trip_point_desc;
108 };
109 
110 /*
111  * SENSOR_DESCRIPTION_GET
112  */
113 
114  #define SCMI_SENSOR_DESCS_MAX(MAILBOX_SIZE) \
115     ((sizeof(struct scmi_sensor_protocol_description_get_p2a) < MAILBOX_SIZE) \
116         ? ((MAILBOX_SIZE - \
117             sizeof(struct scmi_sensor_protocol_description_get_p2a)) \
118                 / sizeof(struct scmi_sensor_desc)) \
119         : 0)
120 
121 /*
122  * SENSOR_AXIS_DESCRIPTION_GET
123  */
124 
125 #define SCMI_SENSOR_AXIS_DESCS_MAX(MAILBOX_SIZE) \
126     ((sizeof(struct scmi_sensor_axis_description_get_p2a) < MAILBOX_SIZE) ? \
127          ((MAILBOX_SIZE - \
128            sizeof(struct scmi_sensor_axis_description_get_p2a)) / \
129           sizeof(struct scmi_sensor_axis_desc)) : \
130          0)
131 
132 /*
133  * SENSOR_READ_GET_AXIS_VALUE
134  */
135 
136 #define SCMI_SENSOR_READ_GET_VALUES_MAX(MAILBOX_SIZE) \
137     ((sizeof(struct scmi_sensor_protocol_reading_get_p2a) < MAILBOX_SIZE) ? \
138          ((MAILBOX_SIZE - \
139            sizeof(struct scmi_sensor_protocol_reading_get_p2a)) / \
140           sizeof(struct scmi_sensor_protocol_reading_get_data)) : \
141          0)
142 
143 #define SCMI_SENSOR_DESC_ATTRS_LOW_SENSOR_ASYNC_READING_POS 31
144 #define SCMI_SENSOR_DESC_ATTRS_LOW_SENSOR_EXTENDED_ATTRIBS_POS 8
145 #define SCMI_SENSOR_DESC_ATTRS_LOW_SENSOR_NUM_TRIP_POINTS_POS 0
146 
147 #define SCMI_SENSOR_DESC_ATTRS_LOW_SENSOR_ASYNC_READING_MASK \
148     (UINT32_C(0x1) << SCMI_SENSOR_DESC_ATTRS_LOW_SENSOR_ASYNC_READING_POS)
149 #define SCMI_SENSOR_DESC_ATTRS_LOW_SENSOR_EXTENDED_ATTRIBS_MASK \
150     (UINT32_C(0x1) << SCMI_SENSOR_DESC_ATTRS_LOW_SENSOR_EXTENDED_ATTRIBS_POS)
151 #define SCMI_SENSOR_DESC_ATTRS_LOW_SENSOR_NUM_TRIP_POINTS_MASK \
152     (UINT32_C(0xFF) << SCMI_SENSOR_DESC_ATTRS_LOW_SENSOR_NUM_TRIP_POINTS_POS)
153 
154 #ifdef BUILD_HAS_SCMI_SENSOR_V2
155 #    define SCMI_SENSOR_DESC_ATTRIBUTES_LOW( \
156         ASYNC_READING, EXTENDED_ATTRIBUTES, NUM_TRIP_POINTS) \
157         ( \
158             (((ASYNC_READING) \
159               << SCMI_SENSOR_DESC_ATTRS_LOW_SENSOR_ASYNC_READING_POS) & \
160              SCMI_SENSOR_DESC_ATTRS_LOW_SENSOR_ASYNC_READING_MASK) | \
161             (((EXTENDED_ATTRIBUTES) \
162               << SCMI_SENSOR_DESC_ATTRS_LOW_SENSOR_EXTENDED_ATTRIBS_POS) & \
163              SCMI_SENSOR_DESC_ATTRS_LOW_SENSOR_EXTENDED_ATTRIBS_MASK) | \
164             (((NUM_TRIP_POINTS) \
165               << SCMI_SENSOR_DESC_ATTRS_LOW_SENSOR_NUM_TRIP_POINTS_POS) & \
166              SCMI_SENSOR_DESC_ATTRS_LOW_SENSOR_NUM_TRIP_POINTS_MASK))
167 #else
168 #    define SCMI_SENSOR_DESC_ATTRIBUTES_LOW(ASYNC_READING, NUM_TRIP_POINTS) \
169         ( \
170             (((ASYNC_READING) \
171               << SCMI_SENSOR_DESC_ATTRS_LOW_SENSOR_ASYNC_READING_POS) & \
172              SCMI_SENSOR_DESC_ATTRS_LOW_SENSOR_ASYNC_READING_MASK) | \
173             (((NUM_TRIP_POINTS) \
174               << SCMI_SENSOR_DESC_ATTRS_LOW_SENSOR_NUM_TRIP_POINTS_POS) & \
175              SCMI_SENSOR_DESC_ATTRS_LOW_SENSOR_NUM_TRIP_POINTS_MASK))
176 #endif
177 
178 #define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_TYPE_POS              0U
179 #define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_POS   11U
180 #define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_POS 22U
181 #define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_INTERVAL_POS   27U
182 
183 #define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_TYPE_MASK \
184     (UINT32_C(0xFF) << SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_TYPE_POS)
185 #define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_MASK \
186     (UINT32_C(0x1F) << SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_POS)
187 #define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_MASK \
188     (UINT32_C(0x1F) \
189         << SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_POS)
190 #define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_INTERVAL_MASK \
191     (UINT32_C(0x1F) << SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_INTERVAL_POS)
192 
193 #define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_MAX \
194     (int32_t)(SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_MASK >> 1U)
195 #define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_MIN \
196     (-(SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_MAX + 1))
197 
198 #define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_MAX \
199     (int32_t)(SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_INTERVAL_MASK >> 1U)
200 #define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_MIN \
201     (-(SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_MAX + 1))
202 
203 #define SCMI_SENSOR_DESC_ATTRIBUTES_HIGH( \
204     SENSOR_TYPE, UNIT_MULTIPLIER, UPDATE_MULTIPLIER, UPDATE_INTERVAL) \
205     (((((unsigned int)SENSOR_TYPE) \
206        << SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_TYPE_POS) & \
207       SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_TYPE_MASK) | \
208      ((((unsigned int)UNIT_MULTIPLIER) \
209        << SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_POS) & \
210       SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_MASK) | \
211      ((((unsigned int)UPDATE_MULTIPLIER) \
212        << SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_POS) & \
213       SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_MASK) | \
214      ((((unsigned int)UPDATE_INTERVAL) \
215        << SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_INTERVAL_POS) & \
216       SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_INTERVAL_MASK))
217 
218 #define SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_DESCS_POS              0
219 #define SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_REMAINING_DESCS_POS   16
220 
221 #define SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_DESCS_MASK \
222     (UINT32_C(0xFFF) << SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_DESCS_POS)
223 #define SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_REMAINING_DESCS_MASK \
224     (UINT32_C(0xFFFF) << SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_REMAINING_DESCS_POS)
225 
226 #define SCMI_SENSOR_NUM_SENSOR_FLAGS(NUM_DESCS, NUM_REMAINING_DESCS) \
227     ( \
228         (((NUM_DESCS) << \
229             SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_DESCS_POS) & \
230             SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_DESCS_MASK) | \
231         (((NUM_REMAINING_DESCS) << \
232             SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_REMAINING_DESCS_POS) & \
233             SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_REMAINING_DESCS_MASK) \
234     )
235 
236 #define SCMI_SENSOR_CONFIG_FLAGS_EVENT_CONTROL_POS 0
237 #define SCMI_SENSOR_CONFIG_FLAGS_EVENT_CONTROL_MASK \
238     (UINT32_C(0x1) << SCMI_SENSOR_CONFIG_FLAGS_EVENT_CONTROL_POS)
239 
240 #define SCMI_SENSOR_NAME_LEN    16
241 #define SCMI_SENSOR_AXIS_NAME_LEN 16
242 
243 #define SCMI_SENSOR_TRIP_POINT_FLAGS_RESERVED1_POS 12
244 #define SCMI_SENSOR_TRIP_POINT_FLAGS_ID_POS 4
245 #define SCMI_SENSOR_TRIP_POINT_FLAGS_RESERVED2_POS 2
246 #define SCMI_SENSOR_TRIP_POINT_FLAGS_EV_CTRL_POS 0
247 
248 #define SCMI_SENSOR_TRIP_POINT_FLAGS_RESERVED1_MASK \
249     (UINT32_C(0xFFFFF) << SCMI_SENSOR_TRIP_POINT_FLAGS_RESERVED1_POS)
250 #define SCMI_SENSOR_TRIP_POINT_FLAGS_ID_MASK \
251     (UINT32_C(0xFF) << SCMI_SENSOR_TRIP_POINT_FLAGS_ID_POS)
252 #define SCMI_SENSOR_TRIP_POINT_FLAGS_RESERVED2_MASK \
253     (UINT32_C(0x3) << SCMI_SENSOR_TRIP_POINT_FLAGS_RESERVED2_POS)
254 #define SCMI_SENSOR_TRIP_POINT_FLAGS_EV_CTRL_MASK \
255     (UINT32_C(0x3) << SCMI_SENSOR_TRIP_POINT_FLAGS_EV_CTRL_POS)
256 
257 #define SCMI_SENSOR_TRIP_POINT_EVENT_DESC_DIRECTION_POS 16
258 #define SCMI_SENSOR_TRIP_POINT_EVENT_DESC_ID_POS 0
259 
260 #define SCMI_SENSOR_TRIP_POINT_EVENT_DESC_DIRECTION_MASK \
261     (UINT32_C(0x1) << SCMI_SENSOR_TRIP_POINT_EVENT_DESC_DIRECTION_POS)
262 #define SCMI_SENSOR_TRIP_POINT_EVENT_DESC_ID_MASK \
263     (UINT32_C(0xFF) << SCMI_SENSOR_TRIP_POINT_EVENT_DESC_ID_POS)
264 
265 #define SCMI_SENSOR_TRIP_POINT_EVENT_DESC(DIRECTION, ID) \
266     ((((DIRECTION) << SCMI_SENSOR_TRIP_POINT_EVENT_DESC_DIRECTION_POS) & \
267       SCMI_SENSOR_TRIP_POINT_EVENT_DESC_DIRECTION_MASK) | \
268      (((ID) << SCMI_SENSOR_TRIP_POINT_EVENT_DESC_ID_POS) & \
269       SCMI_SENSOR_TRIP_POINT_EVENT_DESC_ID_MASK))
270 
271 #ifdef BUILD_HAS_SCMI_SENSOR_V2
272 #    define SCMI_SENSOR_AXIS_DESC_ATTRIBUTES_LOW(EXTENDED_ATTRIBUTES) \
273         (((EXTENDED_ATTRIBUTES) \
274           << SCMI_SENSOR_DESC_ATTRS_LOW_SENSOR_EXTENDED_ATTRIBS_POS) & \
275          SCMI_SENSOR_DESC_ATTRS_LOW_SENSOR_EXTENDED_ATTRIBS_MASK)
276 #endif
277 
278 #define SCMI_SENSOR_AXIS_DESC_ATTRIBUTES_HIGH(SENSOR_TYPE, UNIT_MULTIPLIER) \
279     (((((unsigned int)SENSOR_TYPE) \
280        << SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_TYPE_POS) & \
281       SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_TYPE_MASK) | \
282      ((((unsigned int)UNIT_MULTIPLIER) \
283        << SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_POS) & \
284       SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_MASK))
285 
286 struct scmi_sensor_desc {
287     uint32_t sensor_id;
288     uint32_t sensor_attributes_low;
289     uint32_t sensor_attributes_high;
290     char sensor_name[SCMI_SENSOR_NAME_LEN];
291 #ifdef BUILD_HAS_SCMI_SENSOR_V2
292     uint32_t sensor_power;
293     uint32_t sensor_resolution;
294     int32_t sensor_min_range_low;
295     int32_t sensor_min_range_high;
296     int32_t sensor_max_range_low;
297     int32_t sensor_max_range_high;
298 #endif
299 };
300 
301 struct scmi_sensor_protocol_description_get_a2p {
302     uint32_t desc_index;
303 };
304 
305 struct scmi_sensor_protocol_description_get_p2a {
306     int32_t status;
307     uint32_t num_sensor_flags;
308     struct scmi_sensor_desc sensor_desc[];
309 };
310 
311 struct scmi_sensor_axis_desc {
312     uint32_t axis_idx;
313     uint32_t axis_attributes_low;
314     uint32_t axis_attributes_high;
315     char axis_name[SCMI_SENSOR_AXIS_NAME_LEN];
316 #ifdef BUILD_HAS_SCMI_SENSOR_V2
317     uint32_t axis_resolution;
318     int32_t axis_min_range_low;
319     int32_t axis_min_range_high;
320     int32_t axis_max_range_low;
321     int32_t axis_max_range_high;
322 #endif
323 };
324 
325 struct scmi_sensor_axis_description_get_a2p {
326     uint32_t sensor_idx;
327     uint32_t axis_desc_index;
328 };
329 
330 struct scmi_sensor_axis_description_get_p2a {
331     int32_t status;
332     uint32_t num_axis_flags;
333     struct scmi_sensor_axis_desc axis_desc[];
334 };
335 
336 /* Event indices */
337 enum scmi_sensor_event_idx {
338     SCMI_SENSOR_EVENT_IDX_REQUEST,
339     SCMI_SENSOR_EVENT_IDX_COUNT,
340 };
341 
342 /* SCMI sensor notifications indices */
343 enum scmi_sensor_notification_id { SCMI_SENSOR_TRIP_POINT_EVENT = 0x0 };
344 
345 #ifdef BUILD_HAS_SCMI_SENSOR_V2
346 void scmi_sensor_prop_set(
347     struct mod_sensor_complete_info *info,
348     struct scmi_sensor_desc *desc);
349 
350 void scmi_sensor_axis_prop_set(
351     struct mod_sensor_axis_info *axis_values,
352     struct scmi_sensor_axis_desc *desc);
353 
354 /* These values are the defaults taken from the SCMI spec V3.0 */
355 #    define SCMI_SENSOR_EXT_ATTR_POWER          0
356 #    define SCMI_SENSOR_EXT_ATTR_RESOLUTION_VAL 0
357 #    define SCMI_SENSOR_EXT_ATTR_MIN_RANGE_LOW  0
358 #    define SCMI_SENSOR_EXT_ATTR_MIN_RANGE_HIGH 0x80000000
359 #    define SCMI_SENSOR_EXT_ATTR_MAX_RANGE_LOW  0xFFFFFFFF
360 #    define SCMI_SENSOR_EXT_ATTR_MAX_RANGE_HIGH 0x7FFFFFFF
361 #endif
362 
363 /*!
364  * \}
365  */
366 
367 /*!
368  * \}
369  */
370 
371 #endif /* INTERNAL_SCMI_SENSOR_H */
372