1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include <mod_thermal_mgmt.h>
9 #include <mod_thermal_mgmt_extra.h>
10 
11 #include <fwk_id.h>
12 #include <fwk_module.h>
13 #include <fwk_module_idx.h>
14 
15 enum fake_thermal_domains {
16     MOD_THERMAL_MGMT_DOM_0,
17     MOD_THERMAL_MGMT_DOM_1,
18     MOD_THERMAL_MGMT_DOM_COUNT,
19 };
20 
21 #define FAKE_ACTOR_PER_DOMAIN 2
22 
23 enum fake_actors {
24     FAKE_ACTOR_0,
25     FAKE_ACTOR_1,
26     FAKE_ACTOR_2,
27     FAKE_ACTOR_3,
28     FAKE_ACTOR_COUNT,
29 };
30 
31 enum fake_sensors {
32     FAKE_SENSOR_0,
33     FAKE_SENSOR_1,
34     FAKE_SENSOR_COUNT,
35 };
36 
37 enum fake_activity_factor {
38     FAKE_ACTIVITY_FACTOR_0,
39     FAKE_ACTIVITY_FACTOR_COUNT,
40 };
41 
42 enum fake_activity_factor_api {
43     FAKE_ACTIVITY_FACTOR_API,
44     FAKE_ACTIVITY_FACTOR_API_COUNT,
45 };
46 
47 /*
48  * System Power Req module config
49  */
50 static struct mod_thermal_mgmt_actor_config actor_table_domain0[2] = {
51     [0] = {
52         .driver_id = FWK_ID_ELEMENT_INIT(
53             FWK_MODULE_IDX_FAKE_POWER_MODEL,
54             FAKE_ACTOR_0),
55         .dvfs_domain_id = FWK_ID_ELEMENT_INIT(
56             FWK_MODULE_IDX_DVFS,
57             FAKE_ACTOR_0),
58         .weight = 100,
59         .activity_factor =
60             &((struct mod_thermal_mgmt_activity_factor_config){
61                 .driver_id = FWK_ID_ELEMENT_INIT(
62                     FWK_MODULE_IDX_FAKE_ACTIVITY_COUNTER,
63                     FAKE_ACTIVITY_FACTOR_0),
64                 .driver_api_id = FWK_ID_API_INIT(
65                     FWK_MODULE_IDX_FAKE_ACTIVITY_COUNTER,
66                     FAKE_ACTIVITY_FACTOR_API),
67             }),
68     },
69     [1] = {
70         .driver_id = FWK_ID_ELEMENT_INIT(
71             FWK_MODULE_IDX_FAKE_POWER_MODEL,
72             FAKE_ACTOR_1),
73         .dvfs_domain_id =
74             FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_DVFS, FAKE_ACTOR_1),
75         .weight = 100,
76     },
77 };
78 
79 static struct mod_thermal_mgmt_actor_config actor_table_domain1[2] = {
80     [0] = {
81         .driver_id = FWK_ID_ELEMENT_INIT(
82             FWK_MODULE_IDX_FAKE_POWER_MODEL,
83             FAKE_ACTOR_2),
84         .dvfs_domain_id = FWK_ID_ELEMENT_INIT(
85             FWK_MODULE_IDX_DVFS,
86             FAKE_ACTOR_2),
87         .weight = 100,
88     },
89     [1] = {
90         .driver_id = FWK_ID_ELEMENT_INIT(
91             FWK_MODULE_IDX_FAKE_POWER_MODEL,
92             FAKE_ACTOR_3),
93         .dvfs_domain_id = FWK_ID_ELEMENT_INIT(
94             FWK_MODULE_IDX_DVFS,
95             FAKE_ACTOR_3),
96         .weight = 100,
97     },
98 };
99 
100 static struct mod_thermal_mgmt_actor_config
101     *actor_table_domain[MOD_THERMAL_MGMT_DOM_COUNT] = {
102         [MOD_THERMAL_MGMT_DOM_0] = actor_table_domain0,
103         [MOD_THERMAL_MGMT_DOM_1] = actor_table_domain1,
104     };
105 
106 static struct mod_thermal_mgmt_protection_config temp_protection = {
107     .driver_id = fwk_module_id_fake_thermal_protection,
108     .driver_api_id = mod_fake_thermal_protection_api_id,
109     .warn_temp_threshold = 70,
110     .crit_temp_threshold = 80,
111 };
112 
113 static const struct mod_thermal_mgmt_dev_config
114     dev_config_default_table[MOD_THERMAL_MGMT_DOM_COUNT] = {
115     [MOD_THERMAL_MGMT_DOM_0] = {
116         .slow_loop_mult = 2,
117         .tdp = 10,
118         .pi_controller = {
119             .switch_on_temperature = 50,
120             .control_temperature = 60,
121             .integral_cutoff = 0,
122             .integral_max = 100,
123             .k_p_undershoot = 1,
124             .k_p_overshoot = 1,
125             .k_integral = 1,
126         },
127         .sensor_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SENSOR, FAKE_SENSOR_0),
128         .driver_api_id = FWK_ID_API_INIT(
129             FWK_MODULE_IDX_FAKE_POWER_MODEL,
130             0),
131         .thermal_actors_table = actor_table_domain0,
132         .thermal_actors_count = 2,
133         .temp_protection = &temp_protection,
134     },
135     [MOD_THERMAL_MGMT_DOM_1] = {
136         .slow_loop_mult = 2,
137         .tdp = 10,
138         .pi_controller = {
139             .switch_on_temperature = 50,
140             .control_temperature = 60,
141             .integral_cutoff = 0,
142             .integral_max = 100,
143             .k_p_undershoot = 1,
144             .k_p_overshoot = 1,
145             .k_integral = 1,
146         },
147         .sensor_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_SENSOR, FAKE_SENSOR_1),
148         .driver_api_id = FWK_ID_API_INIT(
149             FWK_MODULE_IDX_FAKE_POWER_MODEL,
150             0),
151         .thermal_actors_table = actor_table_domain1,
152         .thermal_actors_count = 2,
153     },
154 };
155 
156 struct mod_thermal_mgmt_dev_config dev_config_table[MOD_THERMAL_MGMT_DOM_COUNT];
157 
158 static const struct fwk_element
159     thermal_mgmt_domains_elem_table[MOD_THERMAL_MGMT_DOM_COUNT + 1] = {
160     [MOD_THERMAL_MGMT_DOM_0] = {
161         .name = "Fake Thermal Domain 0",
162         .data = (struct mod_thermal_mgmt_dev_config *)
163             &dev_config_table[MOD_THERMAL_MGMT_DOM_0],
164     },
165     [MOD_THERMAL_MGMT_DOM_1] = {
166         .name = "Fake Thermal Domain 1",
167         .data = (struct mod_thermal_mgmt_dev_config *)
168             &dev_config_table[MOD_THERMAL_MGMT_DOM_1],
169     },
170     [MOD_THERMAL_MGMT_DOM_COUNT] = { 0 } /* Termination description */
171 };
172 
get_thermal_mgmt_element_table(fwk_id_t module_id)173 static const struct fwk_element *get_thermal_mgmt_element_table(
174     fwk_id_t module_id)
175 {
176     return thermal_mgmt_domains_elem_table;
177 };
178 
179 const struct fwk_module_config config_thermal_mgmt = {
180     .elements = FWK_MODULE_DYNAMIC_ELEMENTS(get_thermal_mgmt_element_table),
181 };
182 
183 static struct mod_thermal_mgmt_protection_api thermal_protection_api = {
184     .warning = mod_thermal_mgmt_protection_api_warning,
185     .critical = mod_thermal_mgmt_protection_api_critical,
186 };
187 
188 static struct mod_sensor_api sensor_api = {
189     .get_data = mod_sensor_get_data,
190 };
191 
192 static struct mod_thermal_mgmt_dev_ctx
193     dev_ctx_table[MOD_THERMAL_MGMT_DOM_COUNT];
194 
195 static struct mod_thermal_mgmt_actor_ctx
196     actor_ctx_table[MOD_THERMAL_MGMT_DOM_COUNT][FAKE_ACTOR_PER_DOMAIN];
197