1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 /*
9  * The use of "primary" and "secondary" may not be in sync with platform
10  * documentation
11  */
12 
13 #include "config_power_domain.h"
14 #include "config_ppu_v0.h"
15 #include "n1sdp_core.h"
16 #include "n1sdp_power_domain.h"
17 
18 #include <mod_n1sdp_remote_pd.h>
19 #include <mod_power_domain.h>
20 #include <mod_ppu_v1.h>
21 #include <mod_system_power.h>
22 
23 #include <fwk_element.h>
24 #include <fwk_id.h>
25 #include <fwk_macros.h>
26 #include <fwk_module.h>
27 #include <fwk_module_idx.h>
28 
29 #include <stdint.h>
30 #include <stdio.h>
31 
32 /* Maximum power domain name size including the null terminator */
33 #define PD_NAME_SIZE 16
34 
35 /* Mask of the allowed states for the systop logical power domain */
36 static const uint32_t systop_logical_allowed_state_mask_table[] = {
37     [0] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_ON_MASK
38 };
39 
40 /* Mask of the allowed states for the systop power domain */
41 static const uint32_t systop_allowed_state_mask_table[] = {
42     [MOD_PD_STATE_OFF] = MOD_PD_STATE_OFF_MASK,
43     [MOD_PD_STATE_ON] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_ON_MASK |
44           (1 << MOD_SYSTEM_POWER_POWER_STATE_SLEEP0) |
45           (1 << MOD_SYSTEM_POWER_POWER_STATE_SLEEP1)
46 };
47 
48 /*
49  * Mask of the allowed states for the top level power domains
50  * (but the cluster power domains) depending on the system states.
51  */
52 static const uint32_t toplevel_allowed_state_mask_table[] = {
53     [MOD_PD_STATE_OFF] = MOD_PD_STATE_OFF_MASK,
54     [MOD_PD_STATE_ON] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_ON_MASK,
55     [MOD_SYSTEM_POWER_POWER_STATE_SLEEP0] = MOD_PD_STATE_OFF_MASK,
56     [MOD_SYSTEM_POWER_POWER_STATE_SLEEP1] = MOD_PD_STATE_OFF_MASK
57 };
58 
59 /*
60  * Mask of the allowed states for the cluster power domain depending on the
61  * system states.
62  */
63 static const uint32_t cluster_pd_allowed_state_mask_table[] = {
64     [MOD_PD_STATE_OFF] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_SLEEP_MASK,
65     [MOD_PD_STATE_ON] = N1SDP_CLUSTER_VALID_STATE_MASK,
66     [MOD_SYSTEM_POWER_POWER_STATE_SLEEP0] = MOD_PD_STATE_OFF_MASK,
67     [MOD_SYSTEM_POWER_POWER_STATE_SLEEP1] = MOD_PD_STATE_OFF_MASK
68 };
69 
70 /* Mask of the allowed states for a core depending on the cluster states. */
71 static const uint32_t core_pd_allowed_state_mask_table[] = {
72     [MOD_PD_STATE_OFF] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_SLEEP_MASK,
73     [MOD_PD_STATE_ON] = N1SDP_CORE_VALID_STATE_MASK,
74     [MOD_PD_STATE_SLEEP] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_SLEEP_MASK,
75     [N1SDP_POWER_DOMAIN_STATE_FUNC_RET] = N1SDP_CORE_VALID_STATE_MASK,
76     [N1SDP_POWER_DOMAIN_STATE_MEM_RET] = MOD_PD_STATE_OFF_MASK
77 };
78 
79 /* Power module specific configuration data (none) */
80 static const struct mod_power_domain_config n1sdp_power_domain_config = { 0 };
81 
82 /* Power domain element table pointer */
83 struct fwk_element *element_table = NULL;
84 
85 /* Power domain element configuration table pointer */
86 struct mod_power_domain_element_config *pd_config_table = NULL;
87 
88 /*
89  * The power domain tree view differs in primary and secondary chips in
90  * multichip use case. In multichip scenario primary SCP sees the power domains
91  * of both local domains and secondary chip's power domain as one single PD
92  * tree. The view will look like:
93  *
94  *                    -----SYSTOP (LOGICAL)-------
95  *                   /                            \
96  *                  /                              \
97  *            ---SYSTOP0--                   ---SYSTOP1--
98  *           /      |     \                 /      |     \
99  *          /       |      \               /       |      \
100  *         /        |       \             /        |       \
101  *    CLUS0       CLUS1    DBGTOP0   CLUS2       CLUS3     DBGTOP1
102  *   /    \      /    \             /    \      /    \
103  * CPU0--CPU1--CPU2--CPU3---------CPU4--CPU5--CPU6--CPU7
104  *
105  * The secondary chip's SCP however looks a single chip view of PD tree having
106  * its own local power domains and looks like below:
107  *
108  *            ---SYSTOP0--
109  *           /      |     \
110  *          /       |      \
111  *         /        |       \
112  *    CLUS0       CLUS1    DBGTOP0
113  *   /    \      /    \
114  * CPU0--CPU1--CPU2--CPU3
115  *
116  * The PD view will be chosen in runtime based on the multichip enable bit
117  * and chip ID value extracted from SCC PLATFORM_CTRL register.
118  */
119 
120 static struct fwk_element n1sdp_pd_single_chip_element_table[] = {
121     [PD_SINGLE_CHIP_IDX_CLUS0CORE0] = {
122         .name = "CLUS0CORE0",
123         .data = &((struct mod_power_domain_element_config) {
124             .attributes.pd_type = MOD_PD_TYPE_CORE,
125             .parent_idx = PD_SINGLE_CHIP_IDX_CLUSTER0,
126             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V1, 0),
127             .api_id = FWK_ID_API_INIT(
128                 FWK_MODULE_IDX_PPU_V1,
129                 MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER),
130             .allowed_state_mask_table = core_pd_allowed_state_mask_table,
131             .allowed_state_mask_table_size =
132                 FWK_ARRAY_SIZE(core_pd_allowed_state_mask_table)
133         }),
134     },
135     [PD_SINGLE_CHIP_IDX_CLUS0CORE1] = {
136         .name = "CLUS0CORE1",
137         .data = &((struct mod_power_domain_element_config) {
138             .attributes.pd_type = MOD_PD_TYPE_CORE,
139             .parent_idx = PD_SINGLE_CHIP_IDX_CLUSTER0,
140             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V1, 1),
141             .api_id = FWK_ID_API_INIT(
142                 FWK_MODULE_IDX_PPU_V1,
143                 MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER),
144             .allowed_state_mask_table = core_pd_allowed_state_mask_table,
145             .allowed_state_mask_table_size =
146                 FWK_ARRAY_SIZE(core_pd_allowed_state_mask_table)
147         }),
148     },
149     [PD_SINGLE_CHIP_IDX_CLUS1CORE0] = {
150         .name = "CLUS1CORE0",
151         .data = &((struct mod_power_domain_element_config) {
152             .attributes.pd_type = MOD_PD_TYPE_CORE,
153             .parent_idx = PD_SINGLE_CHIP_IDX_CLUSTER1,
154             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V1, 2),
155             .api_id = FWK_ID_API_INIT(
156                 FWK_MODULE_IDX_PPU_V1,
157                 MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER),
158             .allowed_state_mask_table = core_pd_allowed_state_mask_table,
159             .allowed_state_mask_table_size =
160                 FWK_ARRAY_SIZE(core_pd_allowed_state_mask_table)
161         }),
162     },
163     [PD_SINGLE_CHIP_IDX_CLUS1CORE1] = {
164         .name = "CLUS1CORE1",
165         .data = &((struct mod_power_domain_element_config) {
166             .attributes.pd_type = MOD_PD_TYPE_CORE,
167             .parent_idx = PD_SINGLE_CHIP_IDX_CLUSTER1,
168             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V1, 3),
169             .api_id = FWK_ID_API_INIT(
170                 FWK_MODULE_IDX_PPU_V1,
171                 MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER),
172             .allowed_state_mask_table = core_pd_allowed_state_mask_table,
173             .allowed_state_mask_table_size =
174                 FWK_ARRAY_SIZE(core_pd_allowed_state_mask_table)
175         }),
176     },
177     [PD_SINGLE_CHIP_IDX_CLUSTER0] = {
178         .name = "CLUS0",
179         .data = &((struct mod_power_domain_element_config) {
180             .attributes.pd_type = MOD_PD_TYPE_CLUSTER,
181             .parent_idx = PD_SINGLE_CHIP_IDX_SYSTOP0,
182             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V1, 4),
183             .api_id = FWK_ID_API_INIT(
184                 FWK_MODULE_IDX_PPU_V1,
185                 MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER),
186             .allowed_state_mask_table = cluster_pd_allowed_state_mask_table,
187             .allowed_state_mask_table_size =
188                 FWK_ARRAY_SIZE(cluster_pd_allowed_state_mask_table)
189         }),
190     },
191     [PD_SINGLE_CHIP_IDX_CLUSTER1] = {
192         .name = "CLUS1",
193         .data = &((struct mod_power_domain_element_config) {
194             .attributes.pd_type = MOD_PD_TYPE_CLUSTER,
195             .parent_idx = PD_SINGLE_CHIP_IDX_SYSTOP0,
196             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V1, 5),
197             .api_id = FWK_ID_API_INIT(
198                 FWK_MODULE_IDX_PPU_V1,
199                 MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER),
200             .allowed_state_mask_table = cluster_pd_allowed_state_mask_table,
201             .allowed_state_mask_table_size =
202                 FWK_ARRAY_SIZE(cluster_pd_allowed_state_mask_table)
203         }),
204     },
205     [PD_SINGLE_CHIP_IDX_DBGTOP0] = {
206         .name = "DBGTOP0",
207         .data = &((struct mod_power_domain_element_config) {
208             .attributes.pd_type = MOD_PD_TYPE_DEVICE_DEBUG,
209             .parent_idx = PD_SINGLE_CHIP_IDX_SYSTOP0,
210             .driver_id = FWK_ID_ELEMENT_INIT(
211                 FWK_MODULE_IDX_PPU_V0, PPU_V0_ELEMENT_IDX_DBGTOP),
212             .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PPU_V0, 0),
213             .allowed_state_mask_table = toplevel_allowed_state_mask_table,
214             .allowed_state_mask_table_size =
215                 FWK_ARRAY_SIZE(toplevel_allowed_state_mask_table)
216         }),
217     },
218     [PD_SINGLE_CHIP_IDX_SYSTOP0] = {
219         .name = "SYSTOP0",
220         .data = &((struct mod_power_domain_element_config) {
221             .attributes.pd_type = MOD_PD_TYPE_SYSTEM,
222             .parent_idx = PD_SINGLE_CHIP_IDX_NONE,
223             .driver_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SYSTEM_POWER),
224             .api_id = FWK_ID_API_INIT(
225                 FWK_MODULE_IDX_SYSTEM_POWER,
226                 MOD_SYSTEM_POWER_API_IDX_PD_DRIVER),
227             .allowed_state_mask_table = systop_allowed_state_mask_table,
228             .allowed_state_mask_table_size =
229                 FWK_ARRAY_SIZE(systop_allowed_state_mask_table)
230         }),
231     },
232     [PD_SINGLE_CHIP_IDX_COUNT] = { 0 },
233 };
234 
235 static struct fwk_element n1sdp_pd_multi_chip_element_table[] = {
236     [PD_MULTI_CHIP_IDX_CLUS0CORE0] = {
237         .name = "CLUS0CORE0",
238         .data = &((struct mod_power_domain_element_config) {
239             .attributes.pd_type = MOD_PD_TYPE_CORE,
240             .parent_idx = PD_MULTI_CHIP_IDX_CLUSTER0,
241             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V1, 0),
242             .api_id = FWK_ID_API_INIT(
243                 FWK_MODULE_IDX_PPU_V1,
244                 MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER),
245             .allowed_state_mask_table = core_pd_allowed_state_mask_table,
246             .allowed_state_mask_table_size =
247                 FWK_ARRAY_SIZE(core_pd_allowed_state_mask_table)
248         }),
249     },
250     [PD_MULTI_CHIP_IDX_CLUS0CORE1] = {
251         .name = "CLUS0CORE1",
252         .data = &((struct mod_power_domain_element_config) {
253             .attributes.pd_type = MOD_PD_TYPE_CORE,
254             .parent_idx = PD_MULTI_CHIP_IDX_CLUSTER0,
255             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V1, 1),
256             .api_id = FWK_ID_API_INIT(
257                 FWK_MODULE_IDX_PPU_V1,
258                 MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER),
259             .allowed_state_mask_table = core_pd_allowed_state_mask_table,
260             .allowed_state_mask_table_size =
261                 FWK_ARRAY_SIZE(core_pd_allowed_state_mask_table)
262         }),
263     },
264     [PD_MULTI_CHIP_IDX_CLUS1CORE0] = {
265         .name = "CLUS1CORE0",
266         .data = &((struct mod_power_domain_element_config) {
267             .attributes.pd_type = MOD_PD_TYPE_CORE,
268             .parent_idx = PD_MULTI_CHIP_IDX_CLUSTER1,
269             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V1, 2),
270             .api_id = FWK_ID_API_INIT(
271                 FWK_MODULE_IDX_PPU_V1,
272                 MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER),
273             .allowed_state_mask_table = core_pd_allowed_state_mask_table,
274             .allowed_state_mask_table_size =
275                 FWK_ARRAY_SIZE(core_pd_allowed_state_mask_table)
276         }),
277     },
278     [PD_MULTI_CHIP_IDX_CLUS1CORE1] = {
279         .name = "CLUS1CORE1",
280         .data = &((struct mod_power_domain_element_config) {
281             .attributes.pd_type = MOD_PD_TYPE_CORE,
282             .parent_idx = PD_MULTI_CHIP_IDX_CLUSTER1,
283             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V1, 3),
284             .api_id = FWK_ID_API_INIT(
285                 FWK_MODULE_IDX_PPU_V1,
286                 MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER),
287             .allowed_state_mask_table = core_pd_allowed_state_mask_table,
288             .allowed_state_mask_table_size =
289                 FWK_ARRAY_SIZE(core_pd_allowed_state_mask_table)
290         }),
291     },
292     [PD_MULTI_CHIP_IDX_CLUS2CORE0] = {
293         .name = "SLV-CLUS0CORE0",
294         .data = &((struct mod_power_domain_element_config) {
295             .attributes.pd_type = MOD_PD_TYPE_CORE,
296             .parent_idx = PD_MULTI_CHIP_IDX_CLUSTER2,
297             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_N1SDP_REMOTE_PD,
298                                              0),
299             .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_N1SDP_REMOTE_PD,
300                                       N1SDP_REMOTE_PD_API_IDX),
301             .allowed_state_mask_table = core_pd_allowed_state_mask_table,
302             .allowed_state_mask_table_size =
303                 FWK_ARRAY_SIZE(core_pd_allowed_state_mask_table)
304         }),
305     },
306     [PD_MULTI_CHIP_IDX_CLUS2CORE1] = {
307         .name = "SLV-CLUS0CORE1",
308         .data = &((struct mod_power_domain_element_config) {
309             .attributes.pd_type = MOD_PD_TYPE_CORE,
310             .parent_idx = PD_MULTI_CHIP_IDX_CLUSTER2,
311             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_N1SDP_REMOTE_PD,
312                                              1),
313             .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_N1SDP_REMOTE_PD,
314                                       N1SDP_REMOTE_PD_API_IDX),
315             .allowed_state_mask_table = core_pd_allowed_state_mask_table,
316             .allowed_state_mask_table_size =
317                 FWK_ARRAY_SIZE(core_pd_allowed_state_mask_table)
318         }),
319     },
320     [PD_MULTI_CHIP_IDX_CLUS3CORE0] = {
321         .name = "SLV-CLUS1CORE0",
322         .data = &((struct mod_power_domain_element_config) {
323             .attributes.pd_type = MOD_PD_TYPE_CORE,
324             .parent_idx = PD_MULTI_CHIP_IDX_CLUSTER3,
325             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_N1SDP_REMOTE_PD,
326                                              2),
327             .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_N1SDP_REMOTE_PD,
328                                       N1SDP_REMOTE_PD_API_IDX),
329             .allowed_state_mask_table = core_pd_allowed_state_mask_table,
330             .allowed_state_mask_table_size =
331                 FWK_ARRAY_SIZE(core_pd_allowed_state_mask_table)
332         }),
333     },
334     [PD_MULTI_CHIP_IDX_CLUS3CORE1] = {
335         .name = "SLV-CLUS1CORE1",
336         .data = &((struct mod_power_domain_element_config) {
337             .attributes.pd_type = MOD_PD_TYPE_CORE,
338             .parent_idx = PD_MULTI_CHIP_IDX_CLUSTER3,
339             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_N1SDP_REMOTE_PD,
340                                              3),
341             .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_N1SDP_REMOTE_PD,
342                                       N1SDP_REMOTE_PD_API_IDX),
343             .allowed_state_mask_table = core_pd_allowed_state_mask_table,
344             .allowed_state_mask_table_size =
345                 FWK_ARRAY_SIZE(core_pd_allowed_state_mask_table)
346         }),
347     },
348     [PD_MULTI_CHIP_IDX_CLUSTER0] = {
349         .name = "CLUS0",
350         .data = &((struct mod_power_domain_element_config) {
351             .attributes.pd_type = MOD_PD_TYPE_CLUSTER,
352             .parent_idx = PD_MULTI_CHIP_IDX_SYSTOP0,
353             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V1, 4),
354             .api_id = FWK_ID_API_INIT(
355                 FWK_MODULE_IDX_PPU_V1,
356                 MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER),
357             .allowed_state_mask_table = cluster_pd_allowed_state_mask_table,
358             .allowed_state_mask_table_size =
359                 FWK_ARRAY_SIZE(cluster_pd_allowed_state_mask_table)
360         }),
361     },
362     [PD_MULTI_CHIP_IDX_CLUSTER1] = {
363         .name = "CLUS1",
364         .data = &((struct mod_power_domain_element_config) {
365             .attributes.pd_type = MOD_PD_TYPE_CLUSTER,
366             .parent_idx = PD_MULTI_CHIP_IDX_SYSTOP0,
367             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V1, 5),
368             .api_id = FWK_ID_API_INIT(
369                 FWK_MODULE_IDX_PPU_V1,
370                 MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER),
371             .allowed_state_mask_table = cluster_pd_allowed_state_mask_table,
372             .allowed_state_mask_table_size =
373                 FWK_ARRAY_SIZE(cluster_pd_allowed_state_mask_table)
374         }),
375     },
376     [PD_MULTI_CHIP_IDX_DBGTOP0] = {
377         .name = "DBGTOP",
378         .data = &((struct mod_power_domain_element_config) {
379             .attributes.pd_type = MOD_PD_TYPE_DEVICE_DEBUG,
380             .parent_idx = PD_MULTI_CHIP_IDX_SYSTOP0,
381             .driver_id = FWK_ID_ELEMENT_INIT(
382                 FWK_MODULE_IDX_PPU_V0, PPU_V0_ELEMENT_IDX_DBGTOP),
383             .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PPU_V0, 0),
384             .allowed_state_mask_table = toplevel_allowed_state_mask_table,
385             .allowed_state_mask_table_size =
386                 FWK_ARRAY_SIZE(toplevel_allowed_state_mask_table)
387         }),
388     },
389     [PD_MULTI_CHIP_IDX_CLUSTER2] = {
390         .name = "SLV-CLUS0",
391         .data = &((struct mod_power_domain_element_config) {
392             .attributes.pd_type = MOD_PD_TYPE_CLUSTER,
393             .parent_idx = PD_MULTI_CHIP_IDX_SYSTOP1,
394             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_N1SDP_REMOTE_PD,
395                                              4),
396             .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_N1SDP_REMOTE_PD,
397                                       N1SDP_REMOTE_PD_API_IDX),
398             .allowed_state_mask_table = cluster_pd_allowed_state_mask_table,
399             .allowed_state_mask_table_size =
400                 FWK_ARRAY_SIZE(cluster_pd_allowed_state_mask_table)
401         }),
402     },
403     [PD_MULTI_CHIP_IDX_CLUSTER3] = {
404         .name = "SLV-CLUS1",
405         .data = &((struct mod_power_domain_element_config) {
406             .attributes.pd_type = MOD_PD_TYPE_CLUSTER,
407             .parent_idx = PD_MULTI_CHIP_IDX_SYSTOP1,
408             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_N1SDP_REMOTE_PD,
409                                              5),
410             .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_N1SDP_REMOTE_PD,
411                                       N1SDP_REMOTE_PD_API_IDX),
412             .allowed_state_mask_table = cluster_pd_allowed_state_mask_table,
413             .allowed_state_mask_table_size =
414                 FWK_ARRAY_SIZE(cluster_pd_allowed_state_mask_table)
415         }),
416     },
417     [PD_MULTI_CHIP_IDX_DBGTOP1] = {
418         .name = "SLV-DBGTOP",
419         .data = &((struct mod_power_domain_element_config) {
420             .attributes.pd_type = MOD_PD_TYPE_DEVICE_DEBUG,
421             .parent_idx = PD_MULTI_CHIP_IDX_SYSTOP1,
422             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_N1SDP_REMOTE_PD,
423                                              6),
424             .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_N1SDP_REMOTE_PD,
425                                       N1SDP_REMOTE_PD_API_IDX),
426             .allowed_state_mask_table = toplevel_allowed_state_mask_table,
427             .allowed_state_mask_table_size =
428                 FWK_ARRAY_SIZE(toplevel_allowed_state_mask_table)
429         }),
430     },
431     [PD_MULTI_CHIP_IDX_SYSTOP0] = {
432         .name = "SYSTOP0",
433         .data = &((struct mod_power_domain_element_config) {
434             .attributes.pd_type = MOD_PD_TYPE_SYSTEM,
435             .parent_idx = PD_MULTI_CHIP_IDX_SYSTOP_LOGICAL,
436             .driver_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SYSTEM_POWER),
437             .api_id = FWK_ID_API_INIT(
438                 FWK_MODULE_IDX_SYSTEM_POWER,
439                 MOD_SYSTEM_POWER_API_IDX_PD_DRIVER),
440             .allowed_state_mask_table = systop_allowed_state_mask_table,
441             .allowed_state_mask_table_size =
442                 FWK_ARRAY_SIZE(systop_allowed_state_mask_table)
443         }),
444     },
445     [PD_MULTI_CHIP_IDX_SYSTOP1] = {
446         .name = "SLV-SYSTOP",
447         .data = &((struct mod_power_domain_element_config) {
448             .attributes.pd_type = MOD_PD_TYPE_SYSTEM,
449             .parent_idx = PD_MULTI_CHIP_IDX_SYSTOP_LOGICAL,
450             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_N1SDP_REMOTE_PD,
451                                              7),
452             .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_N1SDP_REMOTE_PD,
453                                       N1SDP_REMOTE_PD_API_IDX),
454             .allowed_state_mask_table = systop_allowed_state_mask_table,
455             .allowed_state_mask_table_size =
456                 FWK_ARRAY_SIZE(systop_allowed_state_mask_table)
457         }),
458     },
459     [PD_MULTI_CHIP_IDX_SYSTOP_LOGICAL] = {
460         .name = "SYSTOP-LOGICAL",
461         .data = &((struct mod_power_domain_element_config) {
462             .attributes.pd_type = MOD_PD_TYPE_SYSTEM,
463             .parent_idx = PD_MULTI_CHIP_IDX_NONE,
464             .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_N1SDP_REMOTE_PD,
465                                              8),
466             .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_N1SDP_REMOTE_PD,
467                                       N1SDP_REMOTE_PD_API_IDX),
468             .allowed_state_mask_table = systop_logical_allowed_state_mask_table,
469             .allowed_state_mask_table_size =
470                 FWK_ARRAY_SIZE(systop_logical_allowed_state_mask_table)
471         }),
472     },
473     [PD_MULTI_CHIP_IDX_COUNT] = { 0 },
474 };
475 
476 /*
477  * Function definitions with internal linkage
478  */
n1sdp_power_domain_get_element_table(fwk_id_t module_id)479 static const struct fwk_element *n1sdp_power_domain_get_element_table
480     (fwk_id_t module_id)
481 {
482     if (n1sdp_is_multichip_enabled() && (n1sdp_get_chipid() == 0x0)) {
483         return n1sdp_pd_multi_chip_element_table;
484     } else {
485         return n1sdp_pd_single_chip_element_table;
486     }
487 }
488 
489 /*
490  * Power module configuration data
491  */
492 const struct fwk_module_config config_power_domain = {
493     .data = &n1sdp_power_domain_config,
494 
495     .elements =
496         FWK_MODULE_DYNAMIC_ELEMENTS(n1sdp_power_domain_get_element_table),
497 };
498