• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2022 Beken Corporation
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <common/bk_include.h>
16 #include "mailbox_driver_base.h"
17 #include "mailbox_driver.h"
18 #include "icu_driver.h"
19 
20 
21 static const mailbox_config_t mailbox_cfg_map_table[] = MAILBAOX_CONFIG_INFO_TABLE;
22 
23 static mailbox_info_t s_mailbox[ARRAY_SIZE(mailbox_cfg_map_table)] = {NULL};
24 static bool s_mailbox_is_init = false;
25 
26 #define MAILBOX_RETURN_ON_NOT_INIT() do {\
27 		if (!s_mailbox_is_init) {\
28 			return BK_ERR_MAILBOX_NOT_INIT;\
29 		}\
30 	} while(0)
31 
32 #define MAILBOX_RETURN_ON_REPEAT_INIT() do {\
33 		if (s_mailbox_is_init) {\
34 			return BK_ERR_MAILBOX_REPEAT_INIT;\
35 		}\
36 	} while(0)
37 
38 static void mailbox_config(void);
39 static mailbox_id_t mailbox_check_src_dst(mailbox_endpoint_t src, mailbox_endpoint_t dst);
40 static void mailbox_write_data(mailbox_data_t *data, mailbox_id_t id, mailbox_box_num_t box);
41 static void mailbox_receive_data(mailbox_id_t id, mailbox_data_t *data, mailbox_box_num_t box);
42 static void mailbox_receive_isr(mailbox_id_t id);
43 static void mailbox_service0_isr(void);
44 static void mailbox_service1_isr(void);
45 static void mailbox_interrupt_service(mailbox_info_t *mailbox);
46 
47 
bk_mailbox_init(void)48 bk_err_t bk_mailbox_init(void)
49 {
50 	MAILBOX_LOGD("Begin %s\n", __func__);
51 	MAILBOX_RETURN_ON_REPEAT_INIT();
52 	s_mailbox_is_init = true;
53 
54 	mailbox_config();
55 
56 	for(int index = 0; index < ARRAY_SIZE(mailbox_cfg_map_table); index++)
57 	{
58 		if (INT_SRC_NONE == s_mailbox[index].dir.icu_src)
59 			continue;
60 		bk_int_isr_register((s_mailbox[index].dir.icu_src),
61 							(int_group_isr_t)(s_mailbox[index].imp.mailbox_isr), NULL);
62 
63 		mailbox_interrupt_enable(s_mailbox[index].dir.src);
64 
65 	}
66 
67 
68 	MAILBOX_LOGD("End %s\n", __func__);
69 	return BK_OK;
70 }
71 
bk_mailbox_deinit(void)72 bk_err_t bk_mailbox_deinit(void)
73 {
74 	MAILBOX_LOGD("Begin %s\n", __func__);
75 	MAILBOX_RETURN_ON_NOT_INIT();
76 
77 	for(int index = 0; index < ARRAY_SIZE(mailbox_cfg_map_table); index++) {
78 		mailbox_hal_box_init(&(s_mailbox[index].hal));
79 
80 		if (!(int_group_isr_t)(s_mailbox[index].imp.mailbox_isr))
81 			continue;
82 		bk_int_isr_unregister(s_mailbox[index].dir.icu_src);
83 
84 		mailbox_interrupt_disable(s_mailbox[index].dir.src);
85 	}
86 
87 	s_mailbox_is_init = false;
88 	MAILBOX_LOGD("End %s\n", __func__);
89 	return BK_OK;
90 }
91 
mailbox_config(void)92 static void mailbox_config(void)
93 {
94 	uint32_t index;
95 	uint32_t m_id;
96 
97 	MAILBOX_LOGI("%s\n", __func__);
98 
99 	for (index = 0; index < ARRAY_SIZE(mailbox_cfg_map_table); index++) {
100 		m_id = mailbox_cfg_map_table[index].id;
101 		s_mailbox[m_id].hal.id = m_id;
102 		s_mailbox[m_id].dir = mailbox_cfg_map_table[index];
103 		mailbox_interrupt_service(&s_mailbox[m_id]);
104 
105 		if (mailbox_hal_addr_init(&(s_mailbox[m_id].hal)))
106 			MAILBOX_LOGI("%s addr is error!\n", __func__);
107 
108 		MAILBOX_LOGD("%s addr is %x!\n", __func__, s_mailbox[m_id].hal);
109 		mailbox_hal_set_identity(&(s_mailbox[m_id].hal));
110 		mailbox_hal_box_init(&(s_mailbox[m_id].hal));
111 	}
112 }
113 
bk_mailbox_set_param(mailbox_data_t * data,uint32_t p0,uint32_t p1,uint32_t p2,uint32_t p3)114 bk_err_t bk_mailbox_set_param(mailbox_data_t *data, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3)
115 {
116 	MAILBOX_RETURN_ON_NOT_INIT();
117 
118     data->param0 = p0;
119     data->param1 = p1;
120     data->param2 = p2;
121     data->param3 = p3;
122 
123 	return BK_OK;
124 }
125 
mailbox_check_src_dst(mailbox_endpoint_t src,mailbox_endpoint_t dst)126 static mailbox_id_t mailbox_check_src_dst(mailbox_endpoint_t src, mailbox_endpoint_t dst)
127 {
128 	for(int index = 0; index < ARRAY_SIZE(mailbox_cfg_map_table); index++)
129 	{
130 		if (s_mailbox[index].dir.src != src)
131 			continue;
132 		if (s_mailbox[index].dir.dst != dst)
133 			continue;
134 		return s_mailbox[index].hal.id;
135 	}
136 
137 	MAILBOX_LOGD("%s is ERROR!\n", __func__);
138 	return BK_ERR_MAILBOX_SRC_DST;
139 }
140 
mailbox_write_data(mailbox_data_t * data,mailbox_id_t id,mailbox_box_num_t box)141 static void mailbox_write_data(mailbox_data_t *data, mailbox_id_t id, mailbox_box_num_t box)
142 {
143 	mailbox_hal_write_param0(&(s_mailbox[id].hal), data->param0, box);
144 	mailbox_hal_write_param1(&(s_mailbox[id].hal), data->param1, box);
145 	mailbox_hal_write_param2(&(s_mailbox[id].hal), data->param2, box);
146 	mailbox_hal_write_param3(&(s_mailbox[id].hal), data->param3, box);
147 	MAILBOX_LOGD("[MAILBOX_SEND_PARAM]: (%08x, 0x%08x, %d, %d)\r\n", data->param0,
148 				data->param1, data->param2, data->param3);
149 }
150 
bk_mailbox_send(mailbox_data_t * data,mailbox_endpoint_t src,mailbox_endpoint_t dst,void * arg)151 bk_err_t bk_mailbox_send(mailbox_data_t *data, mailbox_endpoint_t src, mailbox_endpoint_t dst, void *arg)
152 {
153 	MAILBOX_RETURN_ON_NOT_INIT();
154 
155 	mailbox_id_t id;
156 	mailbox_box_num_t box;
157 
158 	MAILBOX_LOGD("%s\n", __func__);
159 
160 	id = mailbox_check_src_dst(src, dst);
161 	if (id >= ARRAY_SIZE(mailbox_cfg_map_table))
162 		return BK_ERR_MAILBOX_SRC_DST;
163 
164 	MAILBOX_LOGD("mailbox send to %d\n", dst);
165 	MAILBOX_LOGD("%s addr is %x! id: %d\n", __func__, (s_mailbox[id].hal), id);
166 
167 	if(arg == NULL)
168 	{
169 		int wait_count = 0;
170 
171 		while(wait_count < MAILBOX_SEND_WAIT_COUNT)
172 		{
173 			box = mailbox_hal_check_which_box_ready(&(s_mailbox[id].hal));
174 
175 			if (box != MAILBOX_NONE)
176 			{
177 				break;
178 			}
179 			wait_count++;
180 		}
181 
182 		if (box == MAILBOX_NONE) // mailbox busy
183 			return BK_ERR_MAILBOX_TIMEOUT;
184 	}
185 	else
186 	{
187 		box = (*(uint16_t *)arg) & 0xFF;
188 
189 		if ((box != MAILBOX_BOX0) && (box != MAILBOX_BOX1))
190 		{
191 			return BK_ERR_MAILBOX_ID;
192 		}
193 
194 		if(mailbox_hal_read_box_ready(&(s_mailbox[id].hal), box) != 0)
195 		{
196 			return BK_ERR_MAILBOX_TIMEOUT;  // mailbox busy
197 		}
198 	}
199 
200 	MAILBOX_LOGD("BOX: %x param0: %x, param1: %x, param2: %x, param3: %x\r\n",
201 			      box, data->param0, data->param1, data->param2, data->param3);
202 
203 	mailbox_hal_box_clear_ready(&(s_mailbox[id].hal), box);
204 	mailbox_write_data(data, id, box);
205 	mailbox_hal_box_trigger(&(s_mailbox[id].hal), box);
206 
207 	return BK_OK;
208 
209 }
210 
mailbox_receive_data(mailbox_id_t id,mailbox_data_t * data,mailbox_box_num_t box)211 static void mailbox_receive_data(mailbox_id_t id, mailbox_data_t *data, mailbox_box_num_t box)
212 {
213 	data->param0 = mailbox_hal_read_param0(&(s_mailbox[id].hal), box);
214 	data->param1 = mailbox_hal_read_param1(&(s_mailbox[id].hal), box);
215 	data->param2 = mailbox_hal_read_param2(&(s_mailbox[id].hal), box);
216 	data->param3 = mailbox_hal_read_param3(&(s_mailbox[id].hal), box);
217 	MAILBOX_LOGD("[MAILBOX_RECEIVE_PARAM]: (%08x, 0x%08x, %d, %d)\r\n", data->param0,
218 				data->param1, data->param2, data->param3);
219 
220 }
221 
mailbox_receive_isr(mailbox_id_t id)222 static void mailbox_receive_isr(mailbox_id_t id)
223 {
224 	mailbox_data_t data;
225 	mailbox_box_num_t box;
226 
227 	MAILBOX_LOGD("%s addr is %x! id: %d\n", __func__, (s_mailbox[id].hal), id);
228 
229 	box = mailbox_hal_check_which_box_trigger(&(s_mailbox[id].hal));
230 	if (box == MAILBOX_NONE) {
231 		MAILBOX_LOGD("%s BOX ERROR\n", __func__);
232 		return;
233 	}
234 
235 	mailbox_receive_data(id, &data, box);
236 
237 	mailbox_hal_box_clear(&(s_mailbox[id].hal), box);
238 
239 	for (int num = 0; num < MAILBOX_CALLBACK_NUMBER; num++)
240 	{	if (s_mailbox[id].imp.rx[num] != NULL)
241 			(s_mailbox[id].imp.rx[num])(&data);
242 	}
243 
244 	MAILBOX_LOGD("[RECIVE_R]: (%08x, 0x%08x, %d, %d)\r\n", data.param0,
245 				data.param1, data.param2, data.param3);
246 }
247 
bk_mailbox_recv_callback_register(mailbox_endpoint_t src,mailbox_endpoint_t dst,mailbox_callback_t callback)248  bk_err_t bk_mailbox_recv_callback_register(mailbox_endpoint_t src, mailbox_endpoint_t dst, mailbox_callback_t callback)
249 {
250 	MAILBOX_RETURN_ON_NOT_INIT();
251 
252 	mailbox_id_t id;
253 
254 	MAILBOX_LOGI("%s\n", __func__);
255 
256 	id = mailbox_check_src_dst(src, dst);
257 	if (id >= ARRAY_SIZE(mailbox_cfg_map_table))
258 		return BK_ERR_MAILBOX_SRC_DST;
259 
260 	for (int num = 0; num < MAILBOX_CALLBACK_NUMBER; num++)
261 	{
262 		if ((NULL == s_mailbox[id].imp.rx[num]) || (callback == s_mailbox[id].imp.rx[num])) {
263 			s_mailbox[id].imp.rx[num] = callback;
264 			return BK_OK;
265 		}
266 	}
267 
268 	MAILBOX_LOGI("%s mailbox_cb is full\n", __func__);
269 	return BK_ERR_MAILBOX_CALLBACK;
270 }
271 
bk_mailbox_recv_callback_unregister(mailbox_endpoint_t src,mailbox_endpoint_t dst)272 bk_err_t bk_mailbox_recv_callback_unregister(mailbox_endpoint_t src, mailbox_endpoint_t dst)
273 {
274 	MAILBOX_RETURN_ON_NOT_INIT();
275 
276 	mailbox_id_t id;
277 
278 	MAILBOX_LOGI("%s\n", __func__);
279 
280 	id = mailbox_check_src_dst(src, dst);
281 	if (id >= ARRAY_SIZE(mailbox_cfg_map_table))
282 		return BK_ERR_MAILBOX_SRC_DST;
283 
284 	for (int num = 0; num < MAILBOX_CALLBACK_NUMBER; num++)
285 	{	if (s_mailbox[id].imp.rx[num] != NULL) {
286 			s_mailbox[id].imp.rx[num] = NULL;
287 			return BK_OK;
288 		}
289 	}
290 
291 	MAILBOX_LOGI("%s 0x%x not found\n", __func__);
292 
293 	return BK_ERR_MAILBOX_CALLBACK;
294 }
295 
mailbox_service0_isr(void)296 static void mailbox_service0_isr(void)
297 {
298 	MAILBOX_LOGD("%s INTO\n", __func__);
299 
300 	mailbox_id_t id = 0;
301 
302 	for(int index = 0; index < ARRAY_SIZE(mailbox_cfg_map_table); index++)
303 	{
304 		if (s_mailbox[index].dir.icu_src != INT_SRC_MAILBOX0)
305 			continue;
306 		id = s_mailbox[index].dir.id;
307 	}
308 
309 	mailbox_receive_isr(id);
310 	MAILBOX_LOGD("%s OUT\n", __func__);
311 }
312 
mailbox_service1_isr(void)313 static void mailbox_service1_isr(void)
314 {
315 	MAILBOX_LOGD("%s INTO\n", __func__);
316 
317 	mailbox_id_t id = 0;
318 
319 	for(int index = 0; index < ARRAY_SIZE(mailbox_cfg_map_table); index++)
320 	{
321 		if (s_mailbox[index].dir.icu_src != INT_SRC_MAILBOX1)
322 			continue;
323 		id = s_mailbox[index].dir.id;
324 	}
325 	mailbox_receive_isr(id);
326 	MAILBOX_LOGD("%s OUT\n", __func__);
327 }
328 
mailbox_interrupt_service(mailbox_info_t * mailbox)329 static void mailbox_interrupt_service(mailbox_info_t *mailbox)
330 {
331 	switch (mailbox->dir.icu_src){
332 		case INT_SRC_MAILBOX0:
333 			mailbox->imp.mailbox_isr = mailbox_service0_isr;
334 			break;
335 		case INT_SRC_MAILBOX1:
336 			mailbox->imp.mailbox_isr = mailbox_service1_isr;
337 			break;
338 		default:
339 			break;
340 	}
341 }
342 
343 //TWO function for other projects
mailbox_driver_init(void)344 void mailbox_driver_init(void)
345 {
346 	MAILBOX_LOGD("%s mailbox driver INIT!!!\n", __func__);
347 	bk_mailbox_init();
348 
349 }
mailbox_driver_deinit(void)350 void mailbox_driver_deinit(void)
351 {
352 	bk_mailbox_deinit();
353 }
354 
355