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