1 /*
2 * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6 #include <assert.h>
7 #include <stdint.h>
8
9 #include <platform_def.h>
10
11 #include <drivers/scmi-msg.h>
12 #include <drivers/scmi.h>
13 #include <drivers/st/stm32mp1_clk.h>
14 #include <drivers/st/stm32mp_reset.h>
15 #include <dt-bindings/clock/stm32mp1-clks.h>
16 #include <dt-bindings/reset/stm32mp1-resets.h>
17
18 #define TIMEOUT_US_1MS 1000U
19
20 #define SCMI_CLOCK_NAME_SIZE 16U
21 #define SCMI_RSTD_NAME_SIZE 16U
22
23 /*
24 * struct stm32_scmi_clk - Data for the exposed clock
25 * @clock_id: Clock identifier in RCC clock driver
26 * @name: Clock string ID exposed to agent
27 * @enabled: State of the SCMI clock
28 */
29 struct stm32_scmi_clk {
30 unsigned long clock_id;
31 const char *name;
32 bool enabled;
33 };
34
35 /*
36 * struct stm32_scmi_rstd - Data for the exposed reset controller
37 * @reset_id: Reset identifier in RCC reset driver
38 * @name: Reset string ID exposed to agent
39 */
40 struct stm32_scmi_rstd {
41 unsigned long reset_id;
42 const char *name;
43 };
44
45 /* Locate all non-secure SMT message buffers in last page of SYSRAM */
46 #define SMT_BUFFER_BASE STM32MP_SCMI_NS_SHM_BASE
47 #define SMT_BUFFER0_BASE SMT_BUFFER_BASE
48 #define SMT_BUFFER1_BASE (SMT_BUFFER_BASE + 0x200)
49
50 CASSERT((STM32MP_SCMI_NS_SHM_BASE + STM32MP_SCMI_NS_SHM_SIZE) >=
51 (SMT_BUFFER1_BASE + SMT_BUF_SLOT_SIZE),
52 assert_scmi_non_secure_shm_fits_scmi_overall_buffer_size);
53
54 static struct scmi_msg_channel scmi_channel[] = {
55 [0] = {
56 .shm_addr = SMT_BUFFER0_BASE,
57 .shm_size = SMT_BUF_SLOT_SIZE,
58 },
59 [1] = {
60 .shm_addr = SMT_BUFFER1_BASE,
61 .shm_size = SMT_BUF_SLOT_SIZE,
62 },
63 };
64
plat_scmi_get_channel(unsigned int agent_id)65 struct scmi_msg_channel *plat_scmi_get_channel(unsigned int agent_id)
66 {
67 assert(agent_id < ARRAY_SIZE(scmi_channel));
68
69 return &scmi_channel[agent_id];
70 }
71
72 #define CLOCK_CELL(_scmi_id, _id, _name, _init_enabled) \
73 [_scmi_id] = { \
74 .clock_id = _id, \
75 .name = _name, \
76 .enabled = _init_enabled, \
77 }
78
79 static struct stm32_scmi_clk stm32_scmi0_clock[] = {
80 CLOCK_CELL(CK_SCMI0_HSE, CK_HSE, "ck_hse", true),
81 CLOCK_CELL(CK_SCMI0_HSI, CK_HSI, "ck_hsi", true),
82 CLOCK_CELL(CK_SCMI0_CSI, CK_CSI, "ck_csi", true),
83 CLOCK_CELL(CK_SCMI0_LSE, CK_LSE, "ck_lse", true),
84 CLOCK_CELL(CK_SCMI0_LSI, CK_LSI, "ck_lsi", true),
85 CLOCK_CELL(CK_SCMI0_PLL2_Q, PLL2_Q, "pll2_q", true),
86 CLOCK_CELL(CK_SCMI0_PLL2_R, PLL2_R, "pll2_r", true),
87 CLOCK_CELL(CK_SCMI0_MPU, CK_MPU, "ck_mpu", true),
88 CLOCK_CELL(CK_SCMI0_AXI, CK_AXI, "ck_axi", true),
89 CLOCK_CELL(CK_SCMI0_BSEC, BSEC, "bsec", true),
90 CLOCK_CELL(CK_SCMI0_CRYP1, CRYP1, "cryp1", false),
91 CLOCK_CELL(CK_SCMI0_GPIOZ, GPIOZ, "gpioz", false),
92 CLOCK_CELL(CK_SCMI0_HASH1, HASH1, "hash1", false),
93 CLOCK_CELL(CK_SCMI0_I2C4, I2C4_K, "i2c4_k", false),
94 CLOCK_CELL(CK_SCMI0_I2C6, I2C6_K, "i2c6_k", false),
95 CLOCK_CELL(CK_SCMI0_IWDG1, IWDG1, "iwdg1", false),
96 CLOCK_CELL(CK_SCMI0_RNG1, RNG1_K, "rng1_k", true),
97 CLOCK_CELL(CK_SCMI0_RTC, RTC, "ck_rtc", true),
98 CLOCK_CELL(CK_SCMI0_RTCAPB, RTCAPB, "rtcapb", true),
99 CLOCK_CELL(CK_SCMI0_SPI6, SPI6_K, "spi6_k", false),
100 CLOCK_CELL(CK_SCMI0_USART1, USART1_K, "usart1_k", false),
101 };
102
103 static struct stm32_scmi_clk stm32_scmi1_clock[] = {
104 CLOCK_CELL(CK_SCMI1_PLL3_Q, PLL3_Q, "pll3_q", true),
105 CLOCK_CELL(CK_SCMI1_PLL3_R, PLL3_R, "pll3_r", true),
106 CLOCK_CELL(CK_SCMI1_MCU, CK_MCU, "ck_mcu", false),
107 };
108
109 #define RESET_CELL(_scmi_id, _id, _name) \
110 [_scmi_id] = { \
111 .reset_id = _id, \
112 .name = _name, \
113 }
114
115 static struct stm32_scmi_rstd stm32_scmi0_reset_domain[] = {
116 RESET_CELL(RST_SCMI0_SPI6, SPI6_R, "spi6"),
117 RESET_CELL(RST_SCMI0_I2C4, I2C4_R, "i2c4"),
118 RESET_CELL(RST_SCMI0_I2C6, I2C6_R, "i2c6"),
119 RESET_CELL(RST_SCMI0_USART1, USART1_R, "usart1"),
120 RESET_CELL(RST_SCMI0_STGEN, STGEN_R, "stgen"),
121 RESET_CELL(RST_SCMI0_GPIOZ, GPIOZ_R, "gpioz"),
122 RESET_CELL(RST_SCMI0_CRYP1, CRYP1_R, "cryp1"),
123 RESET_CELL(RST_SCMI0_HASH1, HASH1_R, "hash1"),
124 RESET_CELL(RST_SCMI0_RNG1, RNG1_R, "rng1"),
125 RESET_CELL(RST_SCMI0_MDMA, MDMA_R, "mdma"),
126 RESET_CELL(RST_SCMI0_MCU, MCU_R, "mcu"),
127 };
128
129 struct scmi_agent_resources {
130 struct stm32_scmi_clk *clock;
131 size_t clock_count;
132 struct stm32_scmi_rstd *rstd;
133 size_t rstd_count;
134 };
135
136 static const struct scmi_agent_resources agent_resources[] = {
137 [0] = {
138 .clock = stm32_scmi0_clock,
139 .clock_count = ARRAY_SIZE(stm32_scmi0_clock),
140 .rstd = stm32_scmi0_reset_domain,
141 .rstd_count = ARRAY_SIZE(stm32_scmi0_reset_domain),
142 },
143 [1] = {
144 .clock = stm32_scmi1_clock,
145 .clock_count = ARRAY_SIZE(stm32_scmi1_clock),
146 },
147 };
148
find_resource(unsigned int agent_id)149 static const struct scmi_agent_resources *find_resource(unsigned int agent_id)
150 {
151 assert(agent_id < ARRAY_SIZE(agent_resources));
152
153 return &agent_resources[agent_id];
154 }
155
156 #if ENABLE_ASSERTIONS
plat_scmi_protocol_count_paranoid(void)157 static size_t plat_scmi_protocol_count_paranoid(void)
158 {
159 unsigned int n = 0U;
160 unsigned int count = 0U;
161
162 for (n = 0U; n < ARRAY_SIZE(agent_resources); n++) {
163 if (agent_resources[n].clock_count) {
164 count++;
165 break;
166 }
167 }
168
169 for (n = 0U; n < ARRAY_SIZE(agent_resources); n++) {
170 if (agent_resources[n].rstd_count) {
171 count++;
172 break;
173 }
174 }
175
176 return count;
177 }
178 #endif
179
180 static const char vendor[] = "ST";
181 static const char sub_vendor[] = "";
182
plat_scmi_vendor_name(void)183 const char *plat_scmi_vendor_name(void)
184 {
185 return vendor;
186 }
187
plat_scmi_sub_vendor_name(void)188 const char *plat_scmi_sub_vendor_name(void)
189 {
190 return sub_vendor;
191 }
192
193 /* Currently supporting Clocks and Reset Domains */
194 static const uint8_t plat_protocol_list[] = {
195 SCMI_PROTOCOL_ID_CLOCK,
196 SCMI_PROTOCOL_ID_RESET_DOMAIN,
197 0U /* Null termination */
198 };
199
plat_scmi_protocol_count(void)200 size_t plat_scmi_protocol_count(void)
201 {
202 const size_t count = ARRAY_SIZE(plat_protocol_list) - 1U;
203
204 assert(count == plat_scmi_protocol_count_paranoid());
205
206 return count;
207 }
208
plat_scmi_protocol_list(unsigned int agent_id __unused)209 const uint8_t *plat_scmi_protocol_list(unsigned int agent_id __unused)
210 {
211 assert(plat_scmi_protocol_count_paranoid() ==
212 (ARRAY_SIZE(plat_protocol_list) - 1U));
213
214 return plat_protocol_list;
215 }
216
217 /*
218 * Platform SCMI clocks
219 */
find_clock(unsigned int agent_id,unsigned int scmi_id)220 static struct stm32_scmi_clk *find_clock(unsigned int agent_id,
221 unsigned int scmi_id)
222 {
223 const struct scmi_agent_resources *resource = find_resource(agent_id);
224 size_t n = 0U;
225
226 if (resource != NULL) {
227 for (n = 0U; n < resource->clock_count; n++) {
228 if (n == scmi_id) {
229 return &resource->clock[n];
230 }
231 }
232 }
233
234 return NULL;
235 }
236
plat_scmi_clock_count(unsigned int agent_id)237 size_t plat_scmi_clock_count(unsigned int agent_id)
238 {
239 const struct scmi_agent_resources *resource = find_resource(agent_id);
240
241 if (resource == NULL) {
242 return 0U;
243 }
244
245 return resource->clock_count;
246 }
247
plat_scmi_clock_get_name(unsigned int agent_id,unsigned int scmi_id)248 const char *plat_scmi_clock_get_name(unsigned int agent_id,
249 unsigned int scmi_id)
250 {
251 struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id);
252
253 if ((clock == NULL) ||
254 !stm32mp_nsec_can_access_clock(clock->clock_id)) {
255 return NULL;
256 }
257
258 return clock->name;
259 }
260
plat_scmi_clock_rates_array(unsigned int agent_id,unsigned int scmi_id,unsigned long * array,size_t * nb_elts)261 int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id,
262 unsigned long *array, size_t *nb_elts)
263 {
264 struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id);
265
266 if (clock == NULL) {
267 return SCMI_NOT_FOUND;
268 }
269
270 if (!stm32mp_nsec_can_access_clock(clock->clock_id)) {
271 return SCMI_DENIED;
272 }
273
274 if (array == NULL) {
275 *nb_elts = 1U;
276 } else if (*nb_elts == 1U) {
277 *array = stm32mp_clk_get_rate(clock->clock_id);
278 } else {
279 return SCMI_GENERIC_ERROR;
280 }
281
282 return SCMI_SUCCESS;
283 }
284
plat_scmi_clock_get_rate(unsigned int agent_id,unsigned int scmi_id)285 unsigned long plat_scmi_clock_get_rate(unsigned int agent_id,
286 unsigned int scmi_id)
287 {
288 struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id);
289
290 if ((clock == NULL) ||
291 !stm32mp_nsec_can_access_clock(clock->clock_id)) {
292 return 0U;
293 }
294
295 return stm32mp_clk_get_rate(clock->clock_id);
296 }
297
plat_scmi_clock_get_state(unsigned int agent_id,unsigned int scmi_id)298 int32_t plat_scmi_clock_get_state(unsigned int agent_id, unsigned int scmi_id)
299 {
300 struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id);
301
302 if ((clock == NULL) ||
303 !stm32mp_nsec_can_access_clock(clock->clock_id)) {
304 return 0U;
305 }
306
307 return (int32_t)clock->enabled;
308 }
309
plat_scmi_clock_set_state(unsigned int agent_id,unsigned int scmi_id,bool enable_not_disable)310 int32_t plat_scmi_clock_set_state(unsigned int agent_id, unsigned int scmi_id,
311 bool enable_not_disable)
312 {
313 struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id);
314
315 if (clock == NULL) {
316 return SCMI_NOT_FOUND;
317 }
318
319 if (!stm32mp_nsec_can_access_clock(clock->clock_id)) {
320 return SCMI_DENIED;
321 }
322
323 if (enable_not_disable) {
324 if (!clock->enabled) {
325 VERBOSE("SCMI clock %u enable\n", scmi_id);
326 stm32mp_clk_enable(clock->clock_id);
327 clock->enabled = true;
328 }
329 } else {
330 if (clock->enabled) {
331 VERBOSE("SCMI clock %u disable\n", scmi_id);
332 stm32mp_clk_disable(clock->clock_id);
333 clock->enabled = false;
334 }
335 }
336
337 return SCMI_SUCCESS;
338 }
339
340 /*
341 * Platform SCMI reset domains
342 */
find_rstd(unsigned int agent_id,unsigned int scmi_id)343 static struct stm32_scmi_rstd *find_rstd(unsigned int agent_id,
344 unsigned int scmi_id)
345 {
346 const struct scmi_agent_resources *resource = find_resource(agent_id);
347 size_t n;
348
349 if (resource != NULL) {
350 for (n = 0U; n < resource->rstd_count; n++) {
351 if (n == scmi_id) {
352 return &resource->rstd[n];
353 }
354 }
355 }
356
357 return NULL;
358 }
359
plat_scmi_rstd_get_name(unsigned int agent_id,unsigned int scmi_id)360 const char *plat_scmi_rstd_get_name(unsigned int agent_id, unsigned int scmi_id)
361 {
362 const struct stm32_scmi_rstd *rstd = find_rstd(agent_id, scmi_id);
363
364 if (rstd == NULL) {
365 return NULL;
366 }
367
368 return rstd->name;
369 }
370
plat_scmi_rstd_count(unsigned int agent_id)371 size_t plat_scmi_rstd_count(unsigned int agent_id)
372 {
373 const struct scmi_agent_resources *resource = find_resource(agent_id);
374
375 if (resource == NULL) {
376 return 0U;
377 }
378
379 return resource->rstd_count;
380 }
381
plat_scmi_rstd_autonomous(unsigned int agent_id,unsigned int scmi_id,uint32_t state)382 int32_t plat_scmi_rstd_autonomous(unsigned int agent_id, unsigned int scmi_id,
383 uint32_t state)
384 {
385 const struct stm32_scmi_rstd *rstd = find_rstd(agent_id, scmi_id);
386
387 if (rstd == NULL) {
388 return SCMI_NOT_FOUND;
389 }
390
391 if (!stm32mp_nsec_can_access_reset(rstd->reset_id)) {
392 return SCMI_DENIED;
393 }
394
395 /* Supports only reset with context loss */
396 if (state != 0U) {
397 return SCMI_NOT_SUPPORTED;
398 }
399
400 VERBOSE("SCMI reset %lu cycle\n", rstd->reset_id);
401
402 if (stm32mp_reset_assert(rstd->reset_id, TIMEOUT_US_1MS)) {
403 return SCMI_HARDWARE_ERROR;
404 }
405
406 if (stm32mp_reset_deassert(rstd->reset_id, TIMEOUT_US_1MS)) {
407 return SCMI_HARDWARE_ERROR;
408 }
409
410 return SCMI_SUCCESS;
411 }
412
plat_scmi_rstd_set_state(unsigned int agent_id,unsigned int scmi_id,bool assert_not_deassert)413 int32_t plat_scmi_rstd_set_state(unsigned int agent_id, unsigned int scmi_id,
414 bool assert_not_deassert)
415 {
416 const struct stm32_scmi_rstd *rstd = find_rstd(agent_id, scmi_id);
417
418 if (rstd == NULL) {
419 return SCMI_NOT_FOUND;
420 }
421
422 if (!stm32mp_nsec_can_access_reset(rstd->reset_id)) {
423 return SCMI_DENIED;
424 }
425
426 if (assert_not_deassert) {
427 VERBOSE("SCMI reset %lu set\n", rstd->reset_id);
428 stm32mp_reset_set(rstd->reset_id);
429 } else {
430 VERBOSE("SCMI reset %lu release\n", rstd->reset_id);
431 stm32mp_reset_release(rstd->reset_id);
432 }
433
434 return SCMI_SUCCESS;
435 }
436
437 /*
438 * Initialize platform SCMI resources
439 */
stm32mp1_init_scmi_server(void)440 void stm32mp1_init_scmi_server(void)
441 {
442 size_t i;
443
444 for (i = 0U; i < ARRAY_SIZE(scmi_channel); i++) {
445 scmi_smt_init_agent_channel(&scmi_channel[i]);
446 }
447
448 for (i = 0U; i < ARRAY_SIZE(agent_resources); i++) {
449 const struct scmi_agent_resources *res = &agent_resources[i];
450 size_t j;
451
452 for (j = 0U; j < res->clock_count; j++) {
453 struct stm32_scmi_clk *clk = &res->clock[j];
454
455 if ((clk->name == NULL) ||
456 (strlen(clk->name) >= SCMI_CLOCK_NAME_SIZE)) {
457 ERROR("Invalid SCMI clock name\n");
458 panic();
459 }
460
461 /* Sync SCMI clocks with their targeted initial state */
462 if (clk->enabled &&
463 stm32mp_nsec_can_access_clock(clk->clock_id)) {
464 stm32mp_clk_enable(clk->clock_id);
465 }
466 }
467
468 for (j = 0U; j < res->rstd_count; j++) {
469 struct stm32_scmi_rstd *rstd = &res->rstd[j];
470
471 if ((rstd->name == NULL) ||
472 (strlen(rstd->name) >= SCMI_RSTD_NAME_SIZE)) {
473 ERROR("Invalid SCMI reset domain name\n");
474 panic();
475 }
476 }
477 }
478 }
479