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