xref: /rk3399_ARM-atf/plat/intel/soc/common/socfpga_sip_svc.c (revision cefb37eb39f1d077b55cd3f00323c8bb215cfe30)
1 /*
2  * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 #include <common/debug.h>
9 #include <common/runtime_svc.h>
10 #include <tools_share/uuid.h>
11 
12 #include "socfpga_mailbox.h"
13 #include "socfpga_sip_svc.h"
14 
15 /* Number of SiP Calls implemented */
16 #define SIP_NUM_CALLS		0x3
17 
18 /* Total buffer the driver can hold */
19 #define FPGA_CONFIG_BUFFER_SIZE 4
20 
21 static int current_block;
22 static int read_block;
23 static int current_buffer;
24 static int send_id;
25 static int rcv_id;
26 static int max_blocks;
27 static uint32_t bytes_per_block;
28 static uint32_t blocks_submitted;
29 
30 struct fpga_config_info {
31 	uint32_t addr;
32 	int size;
33 	int size_written;
34 	uint32_t write_requested;
35 	int subblocks_sent;
36 	int block_number;
37 };
38 
39 /*  SiP Service UUID */
40 DEFINE_SVC_UUID2(intl_svc_uid,
41 		0xa85273b0, 0xe85a, 0x4862, 0xa6, 0x2a,
42 		0xfa, 0x88, 0x88, 0x17, 0x68, 0x81);
43 
44 uint64_t socfpga_sip_handler(uint32_t smc_fid,
45 				   uint64_t x1,
46 				   uint64_t x2,
47 				   uint64_t x3,
48 				   uint64_t x4,
49 				   void *cookie,
50 				   void *handle,
51 				   uint64_t flags)
52 {
53 	ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
54 	SMC_RET1(handle, SMC_UNK);
55 }
56 
57 struct fpga_config_info fpga_config_buffers[FPGA_CONFIG_BUFFER_SIZE];
58 
59 static void intel_fpga_sdm_write_buffer(struct fpga_config_info *buffer)
60 {
61 	uint32_t args[3];
62 
63 	while (max_blocks > 0 && buffer->size > buffer->size_written) {
64 		if (buffer->size - buffer->size_written <=
65 			bytes_per_block) {
66 			args[0] = (1<<8);
67 			args[1] = buffer->addr + buffer->size_written;
68 			args[2] = buffer->size - buffer->size_written;
69 			buffer->size_written +=
70 				buffer->size - buffer->size_written;
71 			buffer->subblocks_sent++;
72 			mailbox_send_cmd_async(
73 				send_id++ % MBOX_MAX_JOB_ID,
74 				MBOX_RECONFIG_DATA,
75 				args, 3, 0);
76 			current_buffer++;
77 			current_buffer %= FPGA_CONFIG_BUFFER_SIZE;
78 		} else {
79 			args[0] = (1<<8);
80 			args[1] = buffer->addr + buffer->size_written;
81 			args[2] = bytes_per_block;
82 			buffer->size_written += bytes_per_block;
83 			mailbox_send_cmd_async(
84 				send_id++ % MBOX_MAX_JOB_ID,
85 				MBOX_RECONFIG_DATA,
86 				args, 3, 0);
87 			buffer->subblocks_sent++;
88 		}
89 		max_blocks--;
90 	}
91 }
92 
93 static int intel_fpga_sdm_write_all(void)
94 {
95 	int i;
96 
97 	for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++)
98 		intel_fpga_sdm_write_buffer(
99 			&fpga_config_buffers[current_buffer]);
100 
101 	return 0;
102 }
103 
104 uint32_t intel_mailbox_fpga_config_isdone(void)
105 {
106 	return intel_mailbox_get_config_status(MBOX_RECONFIG_STATUS);
107 }
108 
109 static int mark_last_buffer_xfer_completed(uint32_t *buffer_addr_completed)
110 {
111 	int i;
112 
113 	for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
114 		if (fpga_config_buffers[i].block_number == current_block) {
115 			fpga_config_buffers[i].subblocks_sent--;
116 			if (fpga_config_buffers[i].subblocks_sent == 0
117 			&& fpga_config_buffers[i].size <=
118 			fpga_config_buffers[i].size_written) {
119 				fpga_config_buffers[i].write_requested = 0;
120 				current_block++;
121 				*buffer_addr_completed =
122 					fpga_config_buffers[i].addr;
123 				return 0;
124 			}
125 		}
126 	}
127 
128 	return -1;
129 }
130 
131 unsigned int address_in_ddr(uint32_t *addr)
132 {
133 	if (((unsigned long long)addr > DRAM_BASE) &&
134 		((unsigned long long)addr < DRAM_BASE + DRAM_SIZE))
135 		return 0;
136 
137 	return -1;
138 }
139 
140 int mailbox_poll_response(int job_id, int urgent, uint32_t *response);
141 
142 int intel_fpga_config_completed_write(uint32_t *completed_addr,
143 					uint32_t *count)
144 {
145 	uint32_t status = INTEL_SIP_SMC_STATUS_OK;
146 	*count = 0;
147 	int resp_len = 0;
148 	uint32_t resp[5];
149 	int all_completed = 1;
150 
151 	while (*count < 3) {
152 
153 		resp_len = mailbox_read_response(
154 			rcv_id % MBOX_MAX_JOB_ID, resp);
155 
156 		if (resp_len < 0)
157 			break;
158 
159 		max_blocks++;
160 		rcv_id++;
161 
162 		if (mark_last_buffer_xfer_completed(
163 			&completed_addr[*count]) == 0)
164 			*count = *count + 1;
165 		else
166 			break;
167 	}
168 
169 	if (*count <= 0) {
170 		if (resp_len != MBOX_NO_RESPONSE &&
171 			resp_len != MBOX_TIMEOUT && resp_len != 0) {
172 			mailbox_clear_response();
173 			return INTEL_SIP_SMC_STATUS_ERROR;
174 		}
175 
176 		*count = 0;
177 	}
178 
179 	intel_fpga_sdm_write_all();
180 
181 	if (*count > 0)
182 		status = INTEL_SIP_SMC_STATUS_OK;
183 	else if (*count == 0)
184 		status = INTEL_SIP_SMC_STATUS_BUSY;
185 
186 	for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
187 		if (fpga_config_buffers[i].write_requested != 0) {
188 			all_completed = 0;
189 			break;
190 		}
191 	}
192 
193 	if (all_completed == 1)
194 		return INTEL_SIP_SMC_STATUS_OK;
195 
196 	return status;
197 }
198 
199 int intel_fpga_config_start(uint32_t config_type)
200 {
201 	uint32_t response[3];
202 	int status = 0;
203 
204 	mailbox_clear_response();
205 
206 	mailbox_send_cmd(1, MBOX_CMD_CANCEL, 0, 0, 0, response);
207 
208 	status = mailbox_send_cmd(1, MBOX_RECONFIG, 0, 0, 0,
209 			response);
210 
211 	if (status < 0)
212 		return status;
213 
214 	max_blocks = response[0];
215 	bytes_per_block = response[1];
216 
217 	for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
218 		fpga_config_buffers[i].size = 0;
219 		fpga_config_buffers[i].size_written = 0;
220 		fpga_config_buffers[i].addr = 0;
221 		fpga_config_buffers[i].write_requested = 0;
222 		fpga_config_buffers[i].block_number = 0;
223 		fpga_config_buffers[i].subblocks_sent = 0;
224 	}
225 
226 	blocks_submitted = 0;
227 	current_block = 0;
228 	read_block = 0;
229 	current_buffer = 0;
230 	send_id = 0;
231 	rcv_id = 0;
232 
233 	return 0;
234 }
235 
236 
237 uint32_t intel_fpga_config_write(uint64_t mem, uint64_t size)
238 {
239 	int i = 0;
240 	uint32_t status = INTEL_SIP_SMC_STATUS_OK;
241 
242 	if (mem < DRAM_BASE || mem > DRAM_BASE + DRAM_SIZE)
243 		status = INTEL_SIP_SMC_STATUS_REJECTED;
244 
245 	if (mem + size > DRAM_BASE + DRAM_SIZE)
246 		status = INTEL_SIP_SMC_STATUS_REJECTED;
247 
248 	for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
249 		if (!fpga_config_buffers[i].write_requested) {
250 			fpga_config_buffers[i].addr = mem;
251 			fpga_config_buffers[i].size = size;
252 			fpga_config_buffers[i].size_written = 0;
253 			fpga_config_buffers[i].write_requested = 1;
254 			fpga_config_buffers[i].block_number =
255 				blocks_submitted++;
256 			fpga_config_buffers[i].subblocks_sent = 0;
257 			break;
258 		}
259 	}
260 
261 
262 	if (i == FPGA_CONFIG_BUFFER_SIZE) {
263 		status = INTEL_SIP_SMC_STATUS_REJECTED;
264 		return status;
265 	} else if (i == FPGA_CONFIG_BUFFER_SIZE - 1) {
266 		status = INTEL_SIP_SMC_STATUS_BUSY;
267 	}
268 
269 	intel_fpga_sdm_write_all();
270 
271 	return status;
272 }
273 
274 /*
275  * This function is responsible for handling all SiP calls from the NS world
276  */
277 
278 uintptr_t sip_smc_handler(uint32_t smc_fid,
279 			 u_register_t x1,
280 			 u_register_t x2,
281 			 u_register_t x3,
282 			 u_register_t x4,
283 			 void *cookie,
284 			 void *handle,
285 			 u_register_t flags)
286 {
287 	uint32_t status = INTEL_SIP_SMC_STATUS_OK;
288 	uint32_t completed_addr[3];
289 	uint32_t count = 0;
290 
291 	switch (smc_fid) {
292 	case SIP_SVC_UID:
293 		/* Return UID to the caller */
294 		SMC_UUID_RET(handle, intl_svc_uid);
295 		break;
296 	case INTEL_SIP_SMC_FPGA_CONFIG_ISDONE:
297 		status = intel_mailbox_fpga_config_isdone();
298 		SMC_RET4(handle, status, 0, 0, 0);
299 		break;
300 	case INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM:
301 		SMC_RET3(handle, INTEL_SIP_SMC_STATUS_OK,
302 			INTEL_SIP_SMC_FPGA_CONFIG_ADDR,
303 			INTEL_SIP_SMC_FPGA_CONFIG_SIZE -
304 				INTEL_SIP_SMC_FPGA_CONFIG_ADDR);
305 		break;
306 	case INTEL_SIP_SMC_FPGA_CONFIG_START:
307 		status = intel_fpga_config_start(x1);
308 		SMC_RET4(handle, status, 0, 0, 0);
309 		break;
310 	case INTEL_SIP_SMC_FPGA_CONFIG_WRITE:
311 		status = intel_fpga_config_write(x1, x2);
312 		SMC_RET4(handle, status, 0, 0, 0);
313 		break;
314 	case INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE:
315 		status = intel_fpga_config_completed_write(completed_addr,
316 								&count);
317 		switch (count) {
318 		case 1:
319 			SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK,
320 				completed_addr[0], 0, 0);
321 			break;
322 		case 2:
323 			SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK,
324 				completed_addr[0],
325 				completed_addr[1], 0);
326 			break;
327 		case 3:
328 			SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK,
329 				completed_addr[0],
330 				completed_addr[1],
331 				completed_addr[2]);
332 			break;
333 		case 0:
334 			SMC_RET4(handle, status, 0, 0, 0);
335 			break;
336 		default:
337 			mailbox_clear_response();
338 			SMC_RET1(handle, INTEL_SIP_SMC_STATUS_ERROR);
339 		}
340 		break;
341 
342 	default:
343 		return socfpga_sip_handler(smc_fid, x1, x2, x3, x4,
344 			cookie, handle, flags);
345 	}
346 }
347 
348 DECLARE_RT_SVC(
349 	socfpga_sip_svc,
350 	OEN_SIP_START,
351 	OEN_SIP_END,
352 	SMC_TYPE_FAST,
353 	NULL,
354 	sip_smc_handler
355 );
356 
357 DECLARE_RT_SVC(
358 	socfpga_sip_svc_std,
359 	OEN_SIP_START,
360 	OEN_SIP_END,
361 	SMC_TYPE_YIELD,
362 	NULL,
363 	sip_smc_handler
364 );
365