xref: /optee_os/core/arch/arm/plat-sam/scmi_server.c (revision 32b3180828fa15a49ccc86ecb4be9d274c140c89)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2019, STMicroelectronics
4  * Copyright (c) 2021, Microchip
5  */
6 
7 #include <at91_clk.h>
8 #include <confine_array_index.h>
9 #include <drivers/scmi-msg.h>
10 #include <drivers/scmi.h>
11 #include <dt-bindings/clock/at91.h>
12 #include <initcall.h>
13 #include <tee_api_defines.h>
14 
15 static_assert(SMT_BUF_SLOT_SIZE <= CFG_SCMI_SHMEM_SIZE);
16 
17 register_phys_mem(MEM_AREA_IO_NSEC, CFG_SCMI_SHMEM_START, CFG_SCMI_SHMEM_SIZE);
18 
19 struct channel_resources {
20 	struct scmi_msg_channel *channel;
21 };
22 
23 static const struct channel_resources scmi_channel[] = {
24 	[0] = {
25 		.channel = &(struct scmi_msg_channel){
26 			.shm_addr = { .pa = CFG_SCMI_SHMEM_START },
27 			.shm_size = SMT_BUF_SLOT_SIZE,
28 		},
29 	},
30 };
31 
32 static const struct channel_resources *find_resource(unsigned int channel_id)
33 {
34 	assert(channel_id < ARRAY_SIZE(scmi_channel));
35 
36 	return scmi_channel + channel_id;
37 }
38 
39 struct scmi_msg_channel *plat_scmi_get_channel(unsigned int channel_id)
40 {
41 	const size_t max_id = ARRAY_SIZE(scmi_channel);
42 	unsigned int confined_id = confine_array_index(channel_id, max_id);
43 
44 	if (channel_id >= max_id)
45 		return NULL;
46 
47 	return find_resource(confined_id)->channel;
48 }
49 
50 static const char vendor[] = "Microchip";
51 static const char sub_vendor[] = "";
52 
53 const char *plat_scmi_vendor_name(void)
54 {
55 	return vendor;
56 }
57 
58 const char *plat_scmi_sub_vendor_name(void)
59 {
60 	return sub_vendor;
61 }
62 
63 /* Currently supporting only SCMI Base protocol */
64 static const uint8_t plat_protocol_list[] = {
65 	SCMI_PROTOCOL_ID_CLOCK,
66 	0 /* Null termination */
67 };
68 
69 size_t plat_scmi_protocol_count(void)
70 {
71 	return ARRAY_SIZE(plat_protocol_list) - 1;
72 }
73 
74 const uint8_t *plat_scmi_protocol_list(unsigned int channel_id __unused)
75 {
76 	return plat_protocol_list;
77 }
78 
79 struct sama5d2_pmc_clk {
80 	unsigned int scmi_id;
81 	unsigned int pmc_type;
82 	unsigned int pmc_id;
83 };
84 
85 static const struct sama5d2_pmc_clk pmc_clks[] = {
86 	{
87 		.scmi_id = AT91_SCMI_CLK_CORE_MCK,
88 		.pmc_type = PMC_TYPE_CORE,
89 		.pmc_id = PMC_MCK
90 	},
91 	{
92 		.scmi_id = AT91_SCMI_CLK_CORE_UTMI,
93 		.pmc_type = PMC_TYPE_CORE,
94 		.pmc_id = PMC_UTMI
95 	},
96 	{
97 		.scmi_id = AT91_SCMI_CLK_CORE_MAIN,
98 		.pmc_type = PMC_TYPE_CORE,
99 		.pmc_id = PMC_MAIN
100 	},
101 	{
102 		.scmi_id = AT91_SCMI_CLK_CORE_MCK2,
103 		.pmc_type = PMC_TYPE_CORE,
104 		.pmc_id = PMC_MCK2
105 	},
106 	{
107 		.scmi_id = AT91_SCMI_CLK_CORE_I2S0_MUX,
108 		.pmc_type = PMC_TYPE_CORE,
109 		.pmc_id = PMC_I2S0_MUX
110 	},
111 	{
112 		.scmi_id = AT91_SCMI_CLK_CORE_I2S1_MUX,
113 		.pmc_type = PMC_TYPE_CORE,
114 		.pmc_id = PMC_I2S1_MUX
115 	},
116 	{
117 		.scmi_id = AT91_SCMI_CLK_CORE_PLLACK,
118 		.pmc_type = PMC_TYPE_CORE,
119 		.pmc_id = PMC_PLLACK
120 	},
121 	{
122 		.scmi_id = AT91_SCMI_CLK_CORE_AUDIOPLLCK,
123 		.pmc_type = PMC_TYPE_CORE,
124 		.pmc_id = PMC_AUDIOPLLCK
125 	},
126 	{
127 		.scmi_id = AT91_SCMI_CLK_CORE_MCK_PRES,
128 		.pmc_type = PMC_TYPE_CORE,
129 		.pmc_id = PMC_MCK_PRES
130 	},
131 	{
132 		.scmi_id = AT91_SCMI_CLK_SYSTEM_DDRCK,
133 		.pmc_type = PMC_TYPE_SYSTEM,
134 		.pmc_id = 2
135 	},
136 	{
137 		.scmi_id = AT91_SCMI_CLK_SYSTEM_LCDCK,
138 		.pmc_type = PMC_TYPE_SYSTEM,
139 		.pmc_id = 3
140 	},
141 	{
142 		.scmi_id = AT91_SCMI_CLK_SYSTEM_UHPCK,
143 		.pmc_type = PMC_TYPE_SYSTEM,
144 		.pmc_id = 6
145 	},
146 	{
147 		.scmi_id = AT91_SCMI_CLK_SYSTEM_UDPCK,
148 		.pmc_type = PMC_TYPE_SYSTEM,
149 		.pmc_id = 7
150 	},
151 	{
152 		.scmi_id = AT91_SCMI_CLK_SYSTEM_PCK0,
153 		.pmc_type = PMC_TYPE_SYSTEM,
154 		.pmc_id = 8
155 	},
156 	{
157 		.scmi_id = AT91_SCMI_CLK_SYSTEM_PCK1,
158 		.pmc_type = PMC_TYPE_SYSTEM,
159 		.pmc_id = 9
160 	},
161 	{
162 		.scmi_id = AT91_SCMI_CLK_SYSTEM_PCK2,
163 		.pmc_type = PMC_TYPE_SYSTEM,
164 		.pmc_id = 10
165 	},
166 	{
167 		.scmi_id = AT91_SCMI_CLK_SYSTEM_ISCCK,
168 		.pmc_type = PMC_TYPE_SYSTEM,
169 		.pmc_id = 18
170 	},
171 	{
172 		.scmi_id = AT91_SCMI_CLK_PERIPH_MACB0_CLK,
173 		.pmc_type = PMC_TYPE_PERIPHERAL,
174 		.pmc_id = 5
175 	},
176 	{
177 		.scmi_id = AT91_SCMI_CLK_PERIPH_TDES_CLK,
178 		.pmc_type = PMC_TYPE_PERIPHERAL,
179 		.pmc_id = 11
180 	},
181 	{
182 		.scmi_id = AT91_SCMI_CLK_PERIPH_MATRIX1_CLK,
183 		.pmc_type = PMC_TYPE_PERIPHERAL,
184 		.pmc_id = 14
185 	},
186 	{
187 		.scmi_id = AT91_SCMI_CLK_PERIPH_HSMC_CLK,
188 		.pmc_type = PMC_TYPE_PERIPHERAL,
189 		.pmc_id = 17
190 	},
191 	{
192 		.scmi_id = AT91_SCMI_CLK_PERIPH_PIOA_CLK,
193 		.pmc_type = PMC_TYPE_PERIPHERAL,
194 		.pmc_id = 18
195 	},
196 	{
197 		.scmi_id = AT91_SCMI_CLK_PERIPH_FLX0_CLK,
198 		.pmc_type = PMC_TYPE_PERIPHERAL,
199 		.pmc_id = 19
200 	},
201 	{
202 		.scmi_id = AT91_SCMI_CLK_PERIPH_FLX1_CLK,
203 		.pmc_type = PMC_TYPE_PERIPHERAL,
204 		.pmc_id = 20
205 	},
206 	{
207 		.scmi_id = AT91_SCMI_CLK_PERIPH_FLX2_CLK,
208 		.pmc_type = PMC_TYPE_PERIPHERAL,
209 		.pmc_id = 21
210 	},
211 	{
212 		.scmi_id = AT91_SCMI_CLK_PERIPH_FLX3_CLK,
213 		.pmc_type = PMC_TYPE_PERIPHERAL,
214 		.pmc_id = 22
215 	},
216 	{
217 		.scmi_id = AT91_SCMI_CLK_PERIPH_FLX4_CLK,
218 		.pmc_type = PMC_TYPE_PERIPHERAL,
219 		.pmc_id = 23
220 	},
221 	{
222 		.scmi_id = AT91_SCMI_CLK_PERIPH_UART0_CLK,
223 		.pmc_type = PMC_TYPE_PERIPHERAL,
224 		.pmc_id = 24
225 	},
226 	{
227 		.scmi_id = AT91_SCMI_CLK_PERIPH_UART1_CLK,
228 		.pmc_type = PMC_TYPE_PERIPHERAL,
229 		.pmc_id = 25
230 	},
231 	{
232 		.scmi_id = AT91_SCMI_CLK_PERIPH_UART2_CLK,
233 		.pmc_type = PMC_TYPE_PERIPHERAL,
234 		.pmc_id = 26
235 	},
236 	{
237 		.scmi_id = AT91_SCMI_CLK_PERIPH_UART3_CLK,
238 		.pmc_type = PMC_TYPE_PERIPHERAL,
239 		.pmc_id = 27
240 	},
241 	{
242 		.scmi_id = AT91_SCMI_CLK_PERIPH_UART4_CLK,
243 		.pmc_type = PMC_TYPE_PERIPHERAL,
244 		.pmc_id = 28
245 	},
246 	{
247 		.scmi_id = AT91_SCMI_CLK_PERIPH_TWI0_CLK,
248 		.pmc_type = PMC_TYPE_PERIPHERAL,
249 		.pmc_id = 29
250 	},
251 	{
252 		.scmi_id = AT91_SCMI_CLK_PERIPH_TWI1_CLK,
253 		.pmc_type = PMC_TYPE_PERIPHERAL,
254 		.pmc_id = 30
255 	},
256 	{
257 		.scmi_id = AT91_SCMI_CLK_PERIPH_SPI0_CLK,
258 		.pmc_type = PMC_TYPE_PERIPHERAL,
259 		.pmc_id = 33
260 	},
261 	{
262 		.scmi_id = AT91_SCMI_CLK_PERIPH_SPI1_CLK,
263 		.pmc_type = PMC_TYPE_PERIPHERAL,
264 		.pmc_id = 34
265 	},
266 	{
267 		.scmi_id = AT91_SCMI_CLK_PERIPH_TCB0_CLK,
268 		.pmc_type = PMC_TYPE_PERIPHERAL,
269 		.pmc_id = 35
270 	},
271 	{
272 		.scmi_id = AT91_SCMI_CLK_PERIPH_TCB1_CLK,
273 		.pmc_type = PMC_TYPE_PERIPHERAL,
274 		.pmc_id = 36
275 	},
276 	{
277 		.scmi_id = AT91_SCMI_CLK_PERIPH_PWM_CLK,
278 		.pmc_type = PMC_TYPE_PERIPHERAL,
279 		.pmc_id = 38
280 	},
281 	{
282 		.scmi_id = AT91_SCMI_CLK_PERIPH_ADC_CLK,
283 		.pmc_type = PMC_TYPE_PERIPHERAL,
284 		.pmc_id = 40
285 	},
286 	{
287 		.scmi_id = AT91_SCMI_CLK_PERIPH_UHPHS_CLK,
288 		.pmc_type = PMC_TYPE_PERIPHERAL,
289 		.pmc_id = 41
290 	},
291 	{
292 		.scmi_id = AT91_SCMI_CLK_PERIPH_UDPHS_CLK,
293 		.pmc_type = PMC_TYPE_PERIPHERAL,
294 		.pmc_id = 42
295 	},
296 	{
297 		.scmi_id = AT91_SCMI_CLK_PERIPH_SSC0_CLK,
298 		.pmc_type = PMC_TYPE_PERIPHERAL,
299 		.pmc_id = 43
300 	},
301 	{
302 		.scmi_id = AT91_SCMI_CLK_PERIPH_SSC1_CLK,
303 		.pmc_type = PMC_TYPE_PERIPHERAL,
304 		.pmc_id = 44
305 	},
306 	{
307 		.scmi_id = AT91_SCMI_CLK_PERIPH_TRNG_CLK,
308 		.pmc_type = PMC_TYPE_PERIPHERAL,
309 		.pmc_id = 47
310 	},
311 	{
312 		.scmi_id = AT91_SCMI_CLK_PERIPH_PDMIC_CLK,
313 		.pmc_type = PMC_TYPE_PERIPHERAL,
314 		.pmc_id = 48
315 	},
316 	{
317 		.scmi_id = AT91_SCMI_CLK_PERIPH_SECURAM_CLK,
318 		.pmc_type = PMC_TYPE_PERIPHERAL,
319 		.pmc_id = 51
320 	},
321 	{
322 		.scmi_id = AT91_SCMI_CLK_PERIPH_I2S0_CLK,
323 		.pmc_type = PMC_TYPE_PERIPHERAL,
324 		.pmc_id = 54
325 	},
326 	{
327 		.scmi_id = AT91_SCMI_CLK_PERIPH_I2S1_CLK,
328 		.pmc_type = PMC_TYPE_PERIPHERAL,
329 		.pmc_id = 55
330 	},
331 	{
332 		.scmi_id = AT91_SCMI_CLK_PERIPH_CAN0_CLK,
333 		.pmc_type = PMC_TYPE_PERIPHERAL,
334 		.pmc_id = 56
335 	},
336 	{
337 		.scmi_id = AT91_SCMI_CLK_PERIPH_CAN1_CLK,
338 		.pmc_type = PMC_TYPE_PERIPHERAL,
339 		.pmc_id = 57
340 	},
341 	{
342 		.scmi_id = AT91_SCMI_CLK_PERIPH_PTC_CLK,
343 		.pmc_type = PMC_TYPE_PERIPHERAL,
344 		.pmc_id = 58
345 	},
346 	{
347 		.scmi_id = AT91_SCMI_CLK_PERIPH_CLASSD_CLK,
348 		.pmc_type = PMC_TYPE_PERIPHERAL,
349 		.pmc_id = 59
350 	},
351 	{
352 		.scmi_id = AT91_SCMI_CLK_PERIPH_DMA0_CLK,
353 		.pmc_type = PMC_TYPE_PERIPHERAL,
354 		.pmc_id = 6
355 	},
356 	{
357 		.scmi_id = AT91_SCMI_CLK_PERIPH_DMA1_CLK,
358 		.pmc_type = PMC_TYPE_PERIPHERAL,
359 		.pmc_id = 7
360 	},
361 	{
362 		.scmi_id = AT91_SCMI_CLK_PERIPH_AES_CLK,
363 		.pmc_type = PMC_TYPE_PERIPHERAL,
364 		.pmc_id = 9
365 	},
366 	{
367 		.scmi_id = AT91_SCMI_CLK_PERIPH_AESB_CLK,
368 		.pmc_type = PMC_TYPE_PERIPHERAL,
369 		.pmc_id = 10
370 	},
371 	{
372 		.scmi_id = AT91_SCMI_CLK_PERIPH_SHA_CLK,
373 		.pmc_type = PMC_TYPE_PERIPHERAL,
374 		.pmc_id = 12
375 	},
376 	{
377 		.scmi_id = AT91_SCMI_CLK_PERIPH_MPDDR_CLK,
378 		.pmc_type = PMC_TYPE_PERIPHERAL,
379 		.pmc_id = 13
380 	},
381 	{
382 		.scmi_id = AT91_SCMI_CLK_PERIPH_MATRIX0_CLK,
383 		.pmc_type = PMC_TYPE_PERIPHERAL,
384 		.pmc_id = 15
385 	},
386 	{
387 		.scmi_id = AT91_SCMI_CLK_PERIPH_SDMMC0_HCLK,
388 		.pmc_type = PMC_TYPE_PERIPHERAL,
389 		.pmc_id = 31
390 	},
391 	{
392 		.scmi_id = AT91_SCMI_CLK_PERIPH_SDMMC1_HCLK,
393 		.pmc_type = PMC_TYPE_PERIPHERAL,
394 		.pmc_id = 32
395 	},
396 	{
397 		.scmi_id = AT91_SCMI_CLK_PERIPH_LCDC_CLK,
398 		.pmc_type = PMC_TYPE_PERIPHERAL,
399 		.pmc_id = 45
400 	},
401 	{
402 		.scmi_id = AT91_SCMI_CLK_PERIPH_ISC_CLK,
403 		.pmc_type = PMC_TYPE_PERIPHERAL,
404 		.pmc_id = 46
405 	},
406 	{
407 		.scmi_id = AT91_SCMI_CLK_PERIPH_QSPI0_CLK,
408 		.pmc_type = PMC_TYPE_PERIPHERAL,
409 		.pmc_id = 52
410 	},
411 	{
412 		.scmi_id = AT91_SCMI_CLK_PERIPH_QSPI1_CLK,
413 		.pmc_type = PMC_TYPE_PERIPHERAL,
414 		.pmc_id = 53
415 	},
416 	{
417 		.scmi_id = AT91_SCMI_CLK_GCK_SDMMC0_GCLK,
418 		.pmc_type = PMC_TYPE_GCK,
419 		.pmc_id = 31
420 	},
421 	{
422 		.scmi_id = AT91_SCMI_CLK_GCK_SDMMC1_GCLK,
423 		.pmc_type = PMC_TYPE_GCK,
424 		.pmc_id = 32
425 	},
426 	{
427 		.scmi_id = AT91_SCMI_CLK_GCK_TCB0_GCLK,
428 		.pmc_type = PMC_TYPE_GCK,
429 		.pmc_id = 35
430 	},
431 	{
432 		.scmi_id = AT91_SCMI_CLK_GCK_TCB1_GCLK,
433 		.pmc_type = PMC_TYPE_GCK,
434 		.pmc_id = 36
435 	},
436 	{
437 		.scmi_id = AT91_SCMI_CLK_GCK_PWM_GCLK,
438 		.pmc_type = PMC_TYPE_GCK,
439 		.pmc_id = 38
440 	},
441 	{
442 		.scmi_id = AT91_SCMI_CLK_GCK_ISC_GCLK,
443 		.pmc_type = PMC_TYPE_GCK,
444 		.pmc_id = 46
445 	},
446 	{
447 		.scmi_id = AT91_SCMI_CLK_GCK_PDMIC_GCLK,
448 		.pmc_type = PMC_TYPE_GCK,
449 		.pmc_id = 48
450 	},
451 	{
452 		.scmi_id = AT91_SCMI_CLK_GCK_I2S0_GCLK,
453 		.pmc_type = PMC_TYPE_GCK,
454 		.pmc_id = 54
455 	},
456 	{
457 		.scmi_id = AT91_SCMI_CLK_GCK_I2S1_GCLK,
458 		.pmc_type = PMC_TYPE_GCK,
459 		.pmc_id = 55
460 	},
461 	{
462 		.scmi_id = AT91_SCMI_CLK_GCK_CAN0_GCLK,
463 		.pmc_type = PMC_TYPE_GCK,
464 		.pmc_id = 56
465 	},
466 	{
467 		.scmi_id = AT91_SCMI_CLK_GCK_CAN1_GCLK,
468 		.pmc_type = PMC_TYPE_GCK,
469 		.pmc_id = 57
470 	},
471 	{
472 		.scmi_id = AT91_SCMI_CLK_GCK_CLASSD_GCLK,
473 		.pmc_type = PMC_TYPE_GCK,
474 		.pmc_id = 59
475 	},
476 	{
477 		.scmi_id = AT91_SCMI_CLK_PROG_PROG0,
478 		.pmc_type = PMC_TYPE_PROGRAMMABLE,
479 		.pmc_id = 0
480 	},
481 	{
482 		.scmi_id = AT91_SCMI_CLK_PROG_PROG1,
483 		.pmc_type = PMC_TYPE_PROGRAMMABLE,
484 		.pmc_id = 1
485 	},
486 	{
487 		.scmi_id = AT91_SCMI_CLK_PROG_PROG2,
488 		.pmc_type = PMC_TYPE_PROGRAMMABLE,
489 		.pmc_id = 2
490 	},
491 };
492 
493 static TEE_Result sam_init_scmi_clk(void)
494 {
495 	unsigned int i = 0;
496 	struct clk *clk = NULL;
497 	TEE_Result res = TEE_ERROR_GENERIC;
498 	const struct sama5d2_pmc_clk *pmc_clk = NULL;
499 
500 	for (i = 0; i < ARRAY_SIZE(pmc_clks); i++) {
501 		pmc_clk = &pmc_clks[i];
502 		res = at91_pmc_clk_get(pmc_clk->pmc_type, pmc_clk->pmc_id,
503 				       &clk);
504 		if (res) {
505 			EMSG("Failed to get PMC clock type %u, id %u",
506 			     pmc_clk->pmc_type, pmc_clk->pmc_id);
507 			return res;
508 		}
509 		res = scmi_clk_add(clk, 0, pmc_clk->scmi_id);
510 		if (res) {
511 			EMSG("Failed to add PMC SCMI clock id %u",
512 			     pmc_clk->scmi_id);
513 			return res;
514 		}
515 	}
516 
517 	clk = at91_sckc_clk_get();
518 	if (!clk)
519 		return TEE_ERROR_GENERIC;
520 
521 	res = scmi_clk_add(clk, 0, AT91_SCMI_CLK_SCKC_SLOWCK_32K);
522 	if (res) {
523 		EMSG("Failed to add slow clock to SCMI clocks");
524 		return res;
525 	}
526 
527 	return TEE_SUCCESS;
528 }
529 
530 /*
531  * Initialize platform SCMI resources
532  */
533 static TEE_Result sam_init_scmi_server(void)
534 {
535 	size_t i = 0;
536 
537 	for (i = 0; i < ARRAY_SIZE(scmi_channel); i++) {
538 		const struct channel_resources *res = scmi_channel + i;
539 		struct scmi_msg_channel *chan = res->channel;
540 
541 		/* Enforce non-secure shm mapped as device memory */
542 		chan->shm_addr.va = (vaddr_t)phys_to_virt(chan->shm_addr.pa,
543 							  MEM_AREA_IO_NSEC, 1);
544 		assert(chan->shm_addr.va);
545 
546 		scmi_smt_init_agent_channel(chan);
547 	}
548 
549 	return sam_init_scmi_clk();
550 }
551 
552 driver_init_late(sam_init_scmi_server);
553