xref: /optee_os/core/arch/arm/plat-stm32mp1/scmi_server.c (revision 69b010d3e7db7dbd8b5025540f7ba8c8df89ee7d)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2019, STMicroelectronics
4  */
5 #include <assert.h>
6 #include <compiler.h>
7 #include <drivers/scmi-msg.h>
8 #include <drivers/scmi.h>
9 #include <dt-bindings/reset/stm32mp1-resets.h>
10 #include <initcall.h>
11 #include <mm/core_memprot.h>
12 #include <mm/core_mmu.h>
13 #include <platform_config.h>
14 #include <stdint.h>
15 #include <speculation_barrier.h>
16 #include <stm32_util.h>
17 #include <string.h>
18 #include <tee_api_defines.h>
19 #include <util.h>
20 
21 #define TIMEOUT_US_1MS		1000
22 
23 #define SCMI_RD_NAME_SIZE	16
24 
25 /*
26  * struct stm32_scmi_rd - Data for the exposed reset controller
27  * @reset_id: Reset identifier in RCC reset driver
28  * @name: Reset string ID exposed to agent
29  */
30 struct stm32_scmi_rd {
31 	unsigned long reset_id;
32 	const char *name;
33 };
34 
35 /* Locate all non-secure SMT message buffers in last page of SYSRAM */
36 #define SMT_BUFFER_BASE		CFG_STM32MP1_SCMI_SHM_BASE
37 #define SMT_BUFFER0_BASE	SMT_BUFFER_BASE
38 #define SMT_BUFFER1_BASE	(SMT_BUFFER_BASE + 0x200)
39 
40 #if (SMT_BUFFER1_BASE + SMT_BUF_SLOT_SIZE > \
41 	CFG_STM32MP1_SCMI_SHM_BASE + CFG_STM32MP1_SCMI_SHM_SIZE)
42 #error "SCMI shared memory mismatch"
43 #endif
44 
45 register_phys_mem(MEM_AREA_IO_NSEC, CFG_STM32MP1_SCMI_SHM_BASE,
46 		  CFG_STM32MP1_SCMI_SHM_SIZE);
47 
48 static struct scmi_msg_channel scmi_channel[] = {
49 	[0] = {
50 		.agent_name = "stm32mp1-agent-0",
51 		.shm_addr = { .pa = SMT_BUFFER0_BASE, },
52 		.shm_size = SMT_BUF_SLOT_SIZE,
53 	},
54 	[1] = {
55 		.agent_name = "stm32mp1-agent-1",
56 		.shm_addr =  { .pa = SMT_BUFFER1_BASE, },
57 		.shm_size = SMT_BUF_SLOT_SIZE,
58 	},
59 };
60 
61 struct scmi_msg_channel *plat_scmi_get_channel(unsigned int agent_id)
62 {
63 	assert(agent_id < ARRAY_SIZE(scmi_channel));
64 
65 	return &scmi_channel[agent_id];
66 }
67 
68 struct scmi_agent_resources {
69 	struct stm32_scmi_clk *clock;
70 	size_t clock_count;
71 	struct stm32_scmi_rd *rd;
72 	size_t rd_count;
73 	struct stm32_scmi_pd *pd;
74 	size_t pd_count;
75 	struct stm32_scmi_perfs *perfs;
76 	size_t perfs_count;
77 };
78 
79 const struct scmi_agent_resources agent_resources[] = {
80 	[0] = { },
81 	[1] = { },
82 };
83 
84 static size_t __maybe_unused plat_scmi_protocol_count_paranoid(void)
85 {
86 	unsigned int n = 0;
87 	unsigned int count = 0;
88 	const size_t agent_count = ARRAY_SIZE(agent_resources);
89 
90 	for (n = 0; n < agent_count; n++)
91 		if (agent_resources[n].clock_count)
92 			break;
93 	if (n < agent_count)
94 		count++;
95 
96 	for (n = 0; n < agent_count; n++)
97 		if (agent_resources[n].rd_count)
98 			break;
99 	if (n < agent_count)
100 		count++;
101 
102 	for (n = 0; n < agent_count; n++)
103 		if (agent_resources[n].pd_count)
104 			break;
105 	if (n < agent_count)
106 		count++;
107 
108 	for (n = 0; n < agent_count; n++)
109 		if (agent_resources[n].perfs_count)
110 			break;
111 	if (n < agent_count)
112 		count++;
113 
114 	return count;
115 }
116 
117 static const char vendor[] = "ST";
118 static const char sub_vendor[] = "";
119 
120 const char *plat_scmi_vendor_name(void)
121 {
122 	return vendor;
123 }
124 
125 const char *plat_scmi_sub_vendor_name(void)
126 {
127 	return sub_vendor;
128 }
129 
130 /* Currently supporting only SCMI Base protocol */
131 static const uint8_t plat_protocol_list[] = {
132 	0 /* Null termination */
133 };
134 
135 size_t plat_scmi_protocol_count(void)
136 {
137 	const size_t count = ARRAY_SIZE(plat_protocol_list) - 1;
138 
139 	assert(count == plat_scmi_protocol_count_paranoid());
140 
141 	return count;
142 }
143 
144 const uint8_t *plat_scmi_protocol_list(unsigned int agent_id __unused)
145 {
146 	assert(plat_scmi_protocol_count_paranoid() ==
147 	       (ARRAY_SIZE(plat_protocol_list) - 1));
148 
149 	return plat_protocol_list;
150 }
151 
152 /*
153  * Initialize platform SCMI resources
154  */
155 static TEE_Result stm32mp1_init_scmi_server(void)
156 {
157 	size_t i = 0;
158 
159 	for (i = 0; i < ARRAY_SIZE(scmi_channel); i++) {
160 		struct scmi_msg_channel *chan = &scmi_channel[i];
161 
162 		/* Enforce non-secure shm mapped as device memory */
163 		chan->shm_addr.va = (vaddr_t)phys_to_virt(chan->shm_addr.pa,
164 							  MEM_AREA_IO_NSEC);
165 		assert(chan->shm_addr.va);
166 
167 		scmi_smt_init_agent_channel(chan);
168 	}
169 
170 	return TEE_SUCCESS;
171 }
172 
173 driver_init_late(stm32mp1_init_scmi_server);
174