1 /*
2 * Arm SCP/MCP Software
3 * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "config_power_domain.h"
9 #include "config_ppu_v0.h"
10 #include "synquacer_core.h"
11
12 #include <power_domain_utils.h>
13
14 #include <mod_power_domain.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 /*
32 * Mask of the allowed states for the cluster power domain depending on the
33 * system states.
34 */
35 static const uint32_t systop_allowed_state_mask_table[] = {
36 [MOD_PD_STATE_OFF] = MOD_PD_STATE_OFF_MASK,
37 [MOD_PD_STATE_ON] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_ON_MASK
38 };
39
40 /*
41 * Mask of the allowed states for the cluster power domain depending on the
42 * system states.
43 */
44 static const uint32_t cluster_pd_allowed_state_mask_table[] = {
45 [MOD_PD_STATE_OFF] = MOD_PD_STATE_OFF_MASK,
46 [MOD_PD_STATE_ON] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_ON_MASK
47 };
48
49 /* Mask of the allowed states for a core depending on the cluster states. */
50 static const uint32_t core_pd_allowed_state_mask_table[] = {
51 [MOD_PD_STATE_OFF] = MOD_PD_STATE_OFF_MASK,
52 [MOD_PD_STATE_ON] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_ON_MASK
53 };
54
55 /* Power module specific configuration data (none) */
56 static const struct mod_power_domain_config synquacer_power_domain_config = {
57 0
58 };
59
60 /* Tree position should follow the ascending order */
61 static struct fwk_element synquacer_power_domain_static_element_table[] = {
62 [PD_STATIC_DEV_IDX_CHILD_SYS3] = {
63 .name = "SYS3",
64 .data = &((struct mod_power_domain_element_config) {
65 .attributes.pd_type = MOD_PD_TYPE_DEVICE,
66 .driver_id = FWK_ID_ELEMENT_INIT(
67 FWK_MODULE_IDX_PPU_V0_SYNQUACER,
68 PPU_V0_ELEMENT_IDX_SYS3),
69 .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PPU_V0_SYNQUACER, 0),
70 .allowed_state_mask_table = systop_allowed_state_mask_table,
71 .allowed_state_mask_table_size =
72 FWK_ARRAY_SIZE(systop_allowed_state_mask_table) }),
73 },
74 [PD_STATIC_DEV_IDX_CHILD_SYS1] = {
75 .name = "SYS1",
76 .data = &((struct mod_power_domain_element_config) {
77 .attributes.pd_type = MOD_PD_TYPE_DEVICE,
78 .driver_id = FWK_ID_ELEMENT_INIT(
79 FWK_MODULE_IDX_PPU_V0_SYNQUACER,
80 PPU_V0_ELEMENT_IDX_SYS1),
81 .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PPU_V0_SYNQUACER, 0),
82 .allowed_state_mask_table = systop_allowed_state_mask_table,
83 .allowed_state_mask_table_size =
84 FWK_ARRAY_SIZE(systop_allowed_state_mask_table) }),
85 },
86 [PD_STATIC_DEV_IDX_CHILD_SYS2] = {
87 .name = "SYS2",
88 .data = &((struct mod_power_domain_element_config) {
89 .attributes.pd_type = MOD_PD_TYPE_DEVICE,
90 .driver_id = FWK_ID_ELEMENT_INIT(
91 FWK_MODULE_IDX_PPU_V0_SYNQUACER,
92 PPU_V0_ELEMENT_IDX_SYS2),
93 .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PPU_V0_SYNQUACER, 0),
94 .allowed_state_mask_table = systop_allowed_state_mask_table,
95 .allowed_state_mask_table_size =
96 FWK_ARRAY_SIZE(systop_allowed_state_mask_table) }),
97 },
98
99 /* PPU_SYS4 is managed by romfw */
100
101 [PD_STATIC_DEV_IDX_CHILD_DEBUG] = {
102 .name = "DEBUG",
103 .data = &((struct mod_power_domain_element_config) {
104 .attributes.pd_type = MOD_PD_TYPE_DEVICE_DEBUG,
105 .driver_id = FWK_ID_ELEMENT_INIT(
106 FWK_MODULE_IDX_PPU_V0_SYNQUACER,
107 PPU_V0_ELEMENT_IDX_DEBUG),
108 .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PPU_V0_SYNQUACER, 0),
109 .allowed_state_mask_table = systop_allowed_state_mask_table,
110 .allowed_state_mask_table_size =
111 FWK_ARRAY_SIZE(systop_allowed_state_mask_table) }),
112 },
113 [PD_STATIC_DEV_IDX_SYSTOP] = {
114 .name = "SYSTOP",
115 .data = &((struct mod_power_domain_element_config) {
116 .attributes.pd_type = MOD_PD_TYPE_SYSTEM,
117 .parent_idx = PD_STATIC_DEV_IDX_NONE,
118 .driver_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SYSTEM_POWER),
119 .api_id = FWK_ID_API_INIT(
120 FWK_MODULE_IDX_SYSTEM_POWER,
121 MOD_SYSTEM_POWER_API_IDX_PD_DRIVER),
122 .allowed_state_mask_table = systop_allowed_state_mask_table,
123 .allowed_state_mask_table_size =
124 FWK_ARRAY_SIZE(systop_allowed_state_mask_table) }),
125 },
126 };
127
synquacer_power_domain_get_element_table(fwk_id_t module_id)128 static const struct fwk_element *synquacer_power_domain_get_element_table(
129 fwk_id_t module_id)
130 {
131 return create_power_domain_element_table(
132 synquacer_core_get_core_count(),
133 synquacer_core_get_cluster_count(),
134 FWK_MODULE_IDX_PPU_V0_SYNQUACER,
135 0,
136 core_pd_allowed_state_mask_table,
137 FWK_ARRAY_SIZE(core_pd_allowed_state_mask_table),
138 cluster_pd_allowed_state_mask_table,
139 FWK_ARRAY_SIZE(cluster_pd_allowed_state_mask_table),
140 synquacer_power_domain_static_element_table,
141 FWK_ARRAY_SIZE(synquacer_power_domain_static_element_table));
142 }
143
144 /*
145 * Power module configuration data
146 */
147 const struct fwk_module_config config_power_domain = {
148 .data = &synquacer_power_domain_config,
149 .elements =
150 FWK_MODULE_DYNAMIC_ELEMENTS(synquacer_power_domain_get_element_table),
151 };
152