1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 #include "config_power_domain.h"
8 #include "platform_core.h"
9 #include "platform_power_domain.h"
10 
11 #include <power_domain_utils.h>
12 
13 #include <mod_power_domain.h>
14 #include <mod_ppu_v1.h>
15 #include <mod_system_power.h>
16 
17 #include <fwk_element.h>
18 #include <fwk_id.h>
19 #include <fwk_macros.h>
20 #include <fwk_mm.h>
21 #include <fwk_module.h>
22 #include <fwk_module_idx.h>
23 
24 #include <stdint.h>
25 #include <stdio.h>
26 #include <string.h>
27 
28 /* Maximum power domain name size including the null terminator */
29 #define PD_NAME_SIZE 12
30 
31 /* Mask of the allowed states for the systop power domain */
32 static const uint32_t systop_allowed_state_mask_table[] = {
33     [0] = MOD_PD_STATE_ON_MASK
34 };
35 
36 /*
37  * Mask of the allowed states for the cluster power domain depending on the
38  * system states.
39  */
40 static const uint32_t cluster_pd_allowed_state_mask_table[] = {
41     [MOD_PD_STATE_OFF] = MOD_PD_STATE_OFF_MASK,
42     [MOD_PD_STATE_ON] = PLATFORM_CLUSTER_VALID_STATE_MASK,
43 };
44 
45 /* Mask of the allowed states for a core depending on the cluster states. */
46 static const uint32_t core_pd_allowed_state_mask_table[] = {
47     [MOD_PD_STATE_OFF] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_SLEEP_MASK,
48     [MOD_PD_STATE_ON] = PLATFORM_CORE_VALID_STATE_MASK,
49 };
50 
51 /* Power module specific configuration data (none) */
52 static const struct mod_power_domain_config platform_power_domain_config = {
53     0
54 };
55 
56 static struct fwk_element platform_power_domain_static_element_table[] = {
57     [PD_STATIC_DEV_IDX_SYSTOP] = {
58         .name = "SYSTOP",
59         .data = &((struct mod_power_domain_element_config) {
60             .attributes.pd_type = MOD_PD_TYPE_SYSTEM,
61             .parent_idx = PD_STATIC_DEV_IDX_NONE,
62             .driver_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SYSTEM_POWER),
63             .api_id = FWK_ID_API_INIT(
64                 FWK_MODULE_IDX_SYSTEM_POWER,
65                 MOD_SYSTEM_POWER_API_IDX_PD_DRIVER),
66             .allowed_state_mask_table = systop_allowed_state_mask_table,
67             .allowed_state_mask_table_size =
68                 FWK_ARRAY_SIZE(systop_allowed_state_mask_table)
69         }),
70     },
71 };
72 
73 /*
74  * Function definitions with internal linkage
75  */
platform_power_domain_get_element_table(fwk_id_t module_id)76 static const struct fwk_element *platform_power_domain_get_element_table(
77     fwk_id_t module_id)
78 {
79     return create_power_domain_element_table(
80         platform_core_get_core_count(),
81         platform_core_get_cluster_count(),
82         FWK_MODULE_IDX_PPU_V1,
83         MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER,
84         core_pd_allowed_state_mask_table,
85         FWK_ARRAY_SIZE(core_pd_allowed_state_mask_table),
86         cluster_pd_allowed_state_mask_table,
87         FWK_ARRAY_SIZE(cluster_pd_allowed_state_mask_table),
88         platform_power_domain_static_element_table,
89         FWK_ARRAY_SIZE(platform_power_domain_static_element_table));
90 }
91 
92 /*
93  * Power module configuration data
94  */
95 const struct fwk_module_config config_power_domain = {
96     .data = &platform_power_domain_config,
97     .elements =
98         FWK_MODULE_DYNAMIC_ELEMENTS(platform_power_domain_get_element_table),
99 };
100