1 /*
2 * Arm SCP/MCP Software
3 * Copyright (c) 2019-2023, Arm Limited and Contributors. All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "config_sensor.h"
9 #include "juno_id.h"
10
11 #if (PLATFORM_VARIANT == JUNO_VARIANT_BOARD)
12 # include <mod_juno_adc.h>
13 # include <mod_juno_pvt.h>
14 # include <mod_juno_xrp7724.h>
15 #endif
16
17 #include <mod_scmi_sensor.h>
18 #include <mod_sensor.h>
19
20 #include <fwk_assert.h>
21 #include <fwk_element.h>
22 #include <fwk_id.h>
23 #include <fwk_macros.h>
24 #include <fwk_mm.h>
25 #include <fwk_module.h>
26 #include <fwk_module_idx.h>
27 #include <fwk_status.h>
28 #include <fwk_string.h>
29
30 #include <string.h>
31
32 #if (PLATFORM_VARIANT == JUNO_VARIANT_BOARD)
33 static const struct fwk_element sensor_element_table_r0[] = {
34 /*
35 * PMIC Sensor
36 */
37 [MOD_JUNO_SENSOR_XRP7724_PMIC_TEMP_IDX] = {
38 .name = "TEMP_PMIC",
39 .data = &(struct mod_sensor_dev_config) {
40 .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_JUNO_XRP7724, 0),
41 .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_JUNO_XRP7724,
42 MOD_JUNO_XRP7724_API_IDX_SENSOR),
43
44 },
45 },
46
47 /*
48 * PVT Sensors
49 */
50 [MOD_JUNO_PVT_SENSOR_VOLT_BIG] = {
51 .name = "VOLT_BIG",
52 .data = (&(struct mod_sensor_dev_config) {
53 .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_JUNO_PVT,
54 JUNO_PVT_GROUP_BIG,
55 0),
56 .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_JUNO_PVT, 0),
57 }),
58 },
59 [MOD_JUNO_PVT_SENSOR_VOLT_LITTLE] = {
60 .name = "VOLT_LITTLE",
61 .data = (&(struct mod_sensor_dev_config) {
62 .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_JUNO_PVT,
63 JUNO_PVT_GROUP_LITTLE,
64 0),
65 .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_JUNO_PVT, 0),
66 }),
67 },
68 [MOD_JUNO_PVT_SENSOR_TEMP_SOC] = {
69 .name = "TEMP_SOC",
70 .data = (&(struct mod_sensor_dev_config) {
71 .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_JUNO_PVT,
72 JUNO_PVT_GROUP_SOC,
73 0),
74 .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_JUNO_PVT, 0),
75 }),
76 },
77 [MOD_JUNO_PVT_SENSOR_VOLT_SYS] = {
78 .name = "VOLT_SYS",
79 .data = (&(struct mod_sensor_dev_config) {
80 .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_JUNO_PVT,
81 JUNO_PVT_GROUP_STDCELL,
82 0),
83 .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_JUNO_PVT, 0),
84 }),
85 },
86
87 /*
88 * ADC Sensors
89 */
90 [MOD_JUNO_SENSOR_VOLT_SYS_IDX] = {
91 .name = "BRD_VOLT_SYS",
92 .data = &((struct mod_sensor_dev_config) {
93 .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_JUNO_ADC,
94 ADC_TYPE_VOLT,
95 ADC_DEV_SYS),
96 .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_JUNO_ADC,
97 MOD_JUNO_ADC_API_IDX_DRIVER),
98 }),
99 },
100 [MOD_JUNO_SENSOR_VOLT_BIG_IDX] = {
101 .name = "BRD_VOLT_BIG",
102 .data = &((struct mod_sensor_dev_config) {
103 .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_JUNO_ADC,
104 ADC_TYPE_VOLT,
105 ADC_DEV_BIG),
106 .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_JUNO_ADC,
107 MOD_JUNO_ADC_API_IDX_DRIVER),
108 }),
109 },
110 [MOD_JUNO_SENSOR_VOLT_LITTLE_IDX] = {
111 .name = "BRD_VOLT_LITTLE",
112 .data = &((struct mod_sensor_dev_config) {
113 .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_JUNO_ADC,
114 ADC_TYPE_VOLT,
115 ADC_DEV_LITTLE),
116 .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_JUNO_ADC,
117 MOD_JUNO_ADC_API_IDX_DRIVER),
118 }),
119 },
120 [MOD_JUNO_SENSOR_VOLT_GPU_IDX] = {
121 .name = "BRD_VOLT_GPU",
122 .data = &((struct mod_sensor_dev_config) {
123 .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_JUNO_ADC,
124 ADC_TYPE_VOLT,
125 ADC_DEV_GPU),
126 .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_JUNO_ADC,
127 MOD_JUNO_ADC_API_IDX_DRIVER),
128 }),
129 },
130
131 # if USE_FULL_SET_SENSORS
132 [MOD_JUNO_SENSOR_AMPS_SYS_IDX] = {
133 .name = "BRD_CURR_SYS",
134 .data = &((struct mod_sensor_dev_config) {
135 .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_JUNO_ADC,
136 ADC_TYPE_CURRENT,
137 ADC_DEV_SYS),
138 .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_JUNO_ADC,
139 MOD_JUNO_ADC_API_IDX_DRIVER),
140 }),
141 },
142 [MOD_JUNO_SENSOR_AMPS_BIG_IDX] = {
143 .name = "BRD_CURR_BIG",
144 .data = &((struct mod_sensor_dev_config) {
145 .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_JUNO_ADC,
146 ADC_TYPE_CURRENT,
147 ADC_DEV_BIG),
148 .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_JUNO_ADC,
149 MOD_JUNO_ADC_API_IDX_DRIVER),
150 }),
151 },
152 [MOD_JUNO_SENSOR_AMPS_LITTLE_IDX] = {
153 .name = "BRD_CURR_LITTLE",
154 .data = &((struct mod_sensor_dev_config) {
155 .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_JUNO_ADC,
156 ADC_TYPE_CURRENT,
157 ADC_DEV_LITTLE),
158 .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_JUNO_ADC,
159 MOD_JUNO_ADC_API_IDX_DRIVER),
160 }),
161 },
162 [MOD_JUNO_SENSOR_AMPS_GPU_IDX] = {
163 .name = "BRD_CURR_GPU",
164 .data = &((struct mod_sensor_dev_config) {
165 .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_JUNO_ADC,
166 ADC_TYPE_CURRENT,
167 ADC_DEV_GPU),
168 .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_JUNO_ADC,
169 MOD_JUNO_ADC_API_IDX_DRIVER),
170 }),
171 },
172 [MOD_JUNO_SENSOR_WATT_SYS_IDX] = {
173 .name = "BRD_PWR_SYS",
174 .data = &((struct mod_sensor_dev_config) {
175 .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_JUNO_ADC,
176 ADC_TYPE_POWER,
177 ADC_DEV_SYS),
178 .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_JUNO_ADC,
179 MOD_JUNO_ADC_API_IDX_DRIVER),
180 }),
181 },
182 [MOD_JUNO_SENSOR_WATT_BIG_IDX] = {
183 .name = "BRD_PWR_BIG",
184 .data = &((struct mod_sensor_dev_config) {
185 .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_JUNO_ADC,
186 ADC_TYPE_POWER,
187 ADC_DEV_BIG),
188 .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_JUNO_ADC,
189 MOD_JUNO_ADC_API_IDX_DRIVER),
190 }),
191 },
192 [MOD_JUNO_SENSOR_WATT_LITTLE_IDX] = {
193 .name = "BRD_PWR_LITTLE",
194 .data = &((struct mod_sensor_dev_config) {
195 .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_JUNO_ADC,
196 ADC_TYPE_POWER,
197 ADC_DEV_LITTLE),
198 .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_JUNO_ADC,
199 MOD_JUNO_ADC_API_IDX_DRIVER),
200 }),
201 },
202 [MOD_JUNO_SENSOR_WATT_GPU_IDX] = {
203 .name = "BRD_PWR_GPU",
204 .data = &((struct mod_sensor_dev_config) {
205 .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_JUNO_ADC,
206 ADC_TYPE_POWER,
207 ADC_DEV_GPU),
208 .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_JUNO_ADC,
209 MOD_JUNO_ADC_API_IDX_DRIVER),
210 }),
211 },
212 [MOD_JUNO_SENSOR_JOULE_SYS_IDX] = {
213 .name = "BRD_ENRG_SYS",
214 .data = &((struct mod_sensor_dev_config) {
215 .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_JUNO_ADC,
216 ADC_TYPE_ENERGY,
217 ADC_DEV_SYS),
218 .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_JUNO_ADC,
219 MOD_JUNO_ADC_API_IDX_DRIVER),
220 }),
221 },
222 [MOD_JUNO_SENSOR_JOULE_BIG_IDX] = {
223 .name = "BRD_ENRG_BIG",
224 .data = &((struct mod_sensor_dev_config) {
225 .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_JUNO_ADC,
226 ADC_TYPE_ENERGY,
227 ADC_DEV_BIG),
228 .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_JUNO_ADC,
229 MOD_JUNO_ADC_API_IDX_DRIVER),
230 }),
231 },
232 [MOD_JUNO_SENSOR_JOULE_LITTLE_IDX] = {
233 .name = "BRD_ENRG_LITTLE",
234 .data = &((struct mod_sensor_dev_config) {
235 .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_JUNO_ADC,
236 ADC_TYPE_ENERGY,
237 ADC_DEV_LITTLE),
238 .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_JUNO_ADC,
239 MOD_JUNO_ADC_API_IDX_DRIVER),
240 }),
241 },
242 [MOD_JUNO_SENSOR_JOULE_GPU_IDX] = {
243 .name = "BRD_ENRG_GPU",
244 .data = &((struct mod_sensor_dev_config) {
245 .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_JUNO_ADC,
246 ADC_TYPE_ENERGY,
247 ADC_DEV_GPU),
248 .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_JUNO_ADC,
249 MOD_JUNO_ADC_API_IDX_DRIVER),
250 }),
251 },
252 # endif
253
254 /* The termination description is added at runtime */
255 };
256
257 # if USE_FULL_SET_SENSORS
258 /* The following table lists PVT sensors available on juno R1 & R2 */
259 static const struct fwk_element pvt_sensors_juno_r1_r2_elem_table[] = {
260 [0] = {
261 .name = "TEMP_BIG",
262 .data = (&(struct mod_sensor_dev_config) {
263 .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_JUNO_PVT,
264 JUNO_PVT_GROUP_BIG,
265 1),
266 .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_JUNO_PVT, 0),
267 }),
268 },
269 [1] = {
270 .name = "TEMP_LITTLE",
271 .data = (&(struct mod_sensor_dev_config) {
272 .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_JUNO_PVT,
273 JUNO_PVT_GROUP_LITTLE,
274 1),
275 .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_JUNO_PVT, 0),
276 }),
277 },
278 [2] = {
279 .name = "TEMP_GPU_0",
280 .data = (&(struct mod_sensor_dev_config) {
281 .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_JUNO_PVT,
282 JUNO_PVT_GROUP_GPU,
283 0),
284 .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_JUNO_PVT, 0),
285 }),
286 },
287 [3] = {
288 .name = "TEMP_GPU_1",
289 .data = (&(struct mod_sensor_dev_config) {
290 .driver_id = FWK_ID_SUB_ELEMENT_INIT(FWK_MODULE_IDX_JUNO_PVT,
291 JUNO_PVT_GROUP_GPU,
292 1),
293 .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_JUNO_PVT, 0),
294 }),
295 },
296 /* The termination description is added at runtime */
297 };
298 #endif
299
300 #elif (PLATFORM_VARIANT == JUNO_VARIANT_FVP)
301
302 /*
303 * When running on a model at least one fake sensor is required to register in
304 * order to properly initialize scmi sensor management.
305 */
306 static const struct fwk_element sensor_element_table_fvp[] = {
307 [0] = {
308 .name = "Fake sensor",
309 .data = &((struct mod_sensor_dev_config) {
310 .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_REG_SENSOR, 0),
311 .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_REG_SENSOR, 0),
312 }),
313 },
314
315 [1] = { 0 } /* Termination description */
316 };
317
318 #endif
319
get_sensor_element_table(fwk_id_t module_id)320 static const struct fwk_element *get_sensor_element_table(fwk_id_t module_id)
321 {
322 #if USE_FULL_SET_SENSORS
323 enum juno_idx_revision rev;
324 size_t pvt_sensor_elem_table_size;
325 #endif
326
327 #if (PLATFORM_VARIANT == JUNO_VARIANT_FVP)
328 return sensor_element_table_fvp;
329 #elif (PLATFORM_VARIANT == JUNO_VARIANT_BOARD)
330 size_t sensor_elem_table_size;
331 struct fwk_element *element_table;
332 sensor_elem_table_size = FWK_ARRAY_SIZE(sensor_element_table_r0);
333
334 # if USE_FULL_SET_SENSORS
335 status = juno_id_get_revision(&rev);
336 if (status != FWK_SUCCESS)
337 return NULL;
338
339 if (rev == JUNO_IDX_REVISION_R0) {
340 /* Just add the termination description */
341 element_table = fwk_mm_calloc(
342 (sensor_elem_table_size + 1), sizeof(struct fwk_element));
343
344 memcpy(
345 element_table,
346 sensor_element_table_r0,
347 sizeof(sensor_element_table_r0));
348 } else {
349 pvt_sensor_elem_table_size =
350 FWK_ARRAY_SIZE(pvt_sensors_juno_r1_r2_elem_table);
351
352 /*
353 * Add additional sensors available on Juno R1 & R2 and the
354 * termination description.
355 */
356 element_table = fwk_mm_calloc(
357 (sensor_elem_table_size + pvt_sensor_elem_table_size + 1),
358 sizeof(struct fwk_element));
359
360 memcpy(
361 element_table,
362 sensor_element_table_r0,
363 sizeof(sensor_element_table_r0));
364
365 memcpy(
366 element_table + sensor_elem_table_size,
367 pvt_sensors_juno_r1_r2_elem_table,
368 sizeof(pvt_sensors_juno_r1_r2_elem_table));
369 }
370 # else
371 /* Just add the termination description */
372 element_table =
373 fwk_mm_calloc((sensor_elem_table_size + 1), sizeof(struct fwk_element));
374 if (element_table == NULL) {
375 return NULL;
376 }
377
378 fwk_str_memcpy(
379 element_table,
380 sensor_element_table_r0,
381 sizeof(sensor_element_table_r0));
382 # endif
383
384 return element_table;
385 #endif
386 }
387
388 struct fwk_module_config config_sensor = {
389 .elements = FWK_MODULE_DYNAMIC_ELEMENTS(get_sensor_element_table),
390 };
391