1 /*
2 * File : mbox.c
3 * Copyright (c) 2006-2021, RT-Thread Development Team
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Change Logs:
8 * Date Author Notes
9 * 2019-08-29 zdzn first version
10 */
11
12 /* mailbox message buffer */
13 #include "mbox.h"
14 #include "mmu.h"
15 //volatile unsigned int __attribute__((aligned(16))) mbox[36];
16 volatile unsigned int *mbox = (volatile unsigned int *) MBOX_ADDR;
17 #define BUS_ADDRESS(phys) (((phys) & ~0xC0000000) | 0xC0000000)
18
19 /**
20 * Make a mailbox call. Returns 0 on failure, non-zero on success
21 */
mbox_call(unsigned char ch,int mmu_enable)22 int mbox_call(unsigned char ch, int mmu_enable)
23 {
24 unsigned int r = (((MBOX_ADDR)&~0xF) | (ch&0xF));
25 if(mmu_enable)
26 r = BUS_ADDRESS(r);
27 /* wait until we can write to the mailbox */
28 do
29 {
30 asm volatile("nop");
31 } while (*MBOX_STATUS & MBOX_FULL);
32 /* write the address of our message to the mailbox with channel identifier */
33 *MBOX_WRITE = r;
34 /* now wait for the response */
35 // rt_kprintf("mailbox request %x\n",r);
36 while(1)
37 {
38 /* is there a response? */
39 do
40 {
41 asm volatile("nop");
42 } while (*MBOX_STATUS & MBOX_EMPTY);
43 /* is it a response to our message? */
44 if (r == *MBOX_READ){
45 /* is it a valid successful response? */
46 // rt_kprintf("mbox: %x, %x, %x, %x, %x, %x, %x, %x\n", mbox[0], mbox[1], mbox[2], mbox[3], mbox[4], mbox[5], mbox[6], mbox[7]);
47 return mbox[1] == MBOX_RESPONSE;
48 }
49 }
50 return 0;
51 }
52
bcm283x_mbox_hardware_get_model(void)53 int bcm283x_mbox_hardware_get_model(void)
54 {
55 mbox[0] = 8*4; // length of the message
56 mbox[1] = MBOX_REQUEST; // this is a request message
57
58 mbox[2] = MBOX_TAG_HARDWARE_GET_MODEL;
59 mbox[3] = 4; // buffer size
60 mbox[4] = 0; // len
61
62 mbox[5] = 0;
63 mbox[6] = 0;
64
65 mbox[7] = MBOX_TAG_LAST;
66 mbox_call(8, MMU_DISABLE);
67
68 return mbox[5];
69 }
70
bcm283x_mbox_hardware_get_revison(void)71 int bcm283x_mbox_hardware_get_revison(void)
72 {
73 mbox[0] = 8*4; // length of the message
74 mbox[1] = MBOX_REQUEST; // this is a request message
75
76 mbox[2] = MBOX_TAG_HARDWARE_GET_REV;
77 mbox[3] = 4; // buffer size
78 mbox[4] = 0; // len
79
80 mbox[5] = 0;
81 mbox[6] = 0;
82
83 mbox[7] = MBOX_TAG_LAST;
84 mbox_call(8, MMU_DISABLE);
85
86 return mbox[5];
87 }
88
bcm283x_mbox_hardware_get_mac_address(uint8_t * mac)89 int bcm283x_mbox_hardware_get_mac_address(uint8_t * mac)
90 {
91 mbox[0] = 8*4; // length of the message
92 mbox[1] = MBOX_REQUEST; // this is a request message
93
94 mbox[2] = MBOX_TAG_HARDWARE_GET_MAC_ADDRESS;
95 mbox[3] = 6; // buffer size
96 mbox[4] = 0; // len
97
98 mbox[5] = 0;
99 mbox[6] = 0;
100
101 mbox[7] = MBOX_TAG_LAST;
102 mbox_call(8, MMU_DISABLE);
103
104 char * mac_str = (char *)&mbox[5];
105 mac[0] = mac_str[0];
106 mac[1] = mac_str[1];
107 mac[2] = mac_str[2];
108 mac[3] = mac_str[3];
109 mac[4] = mac_str[4];
110 mac[5] = mac_str[5];
111 return 0;
112 }
113
114
bcm283x_mbox_hardware_get_serial(rt_uint64_t * sn)115 int bcm283x_mbox_hardware_get_serial(rt_uint64_t* sn)
116 {
117 mbox[0] = 8*4; // length of the message
118 mbox[1] = MBOX_REQUEST; // this is a request message
119
120 mbox[2] = MBOX_TAG_HARDWARE_GET_SERIAL;
121 mbox[3] = 8; // buffer size
122 mbox[4] = 0; // len
123
124 mbox[5] = 0;
125 mbox[6] = 0;
126
127 mbox[7] = MBOX_TAG_LAST;
128 mbox_call(8, MMU_DISABLE);
129
130 sn = (rt_uint64_t *)&mbox[5];
131
132 return 0;
133 }
134
bcm283x_mbox_hardware_get_arm_memory(rt_uint32_t * base,rt_uint32_t * size)135 int bcm283x_mbox_hardware_get_arm_memory(rt_uint32_t * base, rt_uint32_t * size)
136 {
137 mbox[0] = 8*4; // length of the message
138 mbox[1] = MBOX_REQUEST; // this is a request message
139
140 mbox[2] = MBOX_TAG_HARDWARE_GET_ARM_MEMORY;
141 mbox[3] = 8; // buffer size
142 mbox[4] = 0; // len
143
144 mbox[5] = 0;
145 mbox[6] = 0;
146
147 mbox[7] = MBOX_TAG_LAST;
148 mbox_call(8, MMU_DISABLE);
149
150 *base = mbox[5];
151 *size = mbox[6];
152
153 return 0;
154
155 }
156
bcm283x_mbox_hardware_get_vc_memory(rt_uint32_t * base,rt_uint32_t * size)157 int bcm283x_mbox_hardware_get_vc_memory(rt_uint32_t * base, rt_uint32_t * size)
158 {
159 mbox[0] = 8*4; // length of the message
160 mbox[1] = MBOX_REQUEST; // this is a request message
161
162 mbox[2] = MBOX_TAG_HARDWARE_GET_VC_MEMORY;
163 mbox[3] = 8; // buffer size
164 mbox[4] = 0; // len
165
166 mbox[5] = 0;
167 mbox[6] = 0;
168
169 mbox[7] = MBOX_TAG_LAST;
170 mbox_call(8, MMU_DISABLE);
171
172 *base = mbox[5];
173 *size = mbox[6];
174
175 return 0;
176 }
177
bcm283x_mbox_clock_get_turbo(void)178 int bcm283x_mbox_clock_get_turbo(void)
179 {
180 mbox[0] = 8*4; // length of the message
181 mbox[1] = MBOX_REQUEST; // this is a request message
182
183 mbox[2] = MBOX_TAG_CLOCK_GET_TURBO;
184 mbox[3] = 8; // buffer size
185 mbox[4] = 4; // len
186
187 mbox[5] = 0; // id
188 mbox[6] = 0; // val
189
190 mbox[7] = MBOX_TAG_LAST;
191 mbox_call(8, MMU_DISABLE);
192
193 if(mbox[5] != 0)
194 {
195 return -1;
196 }
197
198 return mbox[6];
199 }
200
bcm283x_mbox_clock_set_turbo(int level)201 int bcm283x_mbox_clock_set_turbo(int level)
202 {
203 mbox[0] = 8*4; // length of the message
204 mbox[1] = MBOX_REQUEST; // this is a request message
205
206 mbox[2] = MBOX_TAG_CLOCK_SET_TURBO;
207 mbox[3] = 8; // buffer size
208 mbox[4] = 8; // len
209
210 mbox[5] = 0; // id
211 mbox[6] = level ? 1 : 0;
212
213 mbox[7] = MBOX_TAG_LAST;
214 mbox_call(8, MMU_DISABLE);
215
216 if(mbox[5] != 0)
217 {
218 return -1;
219 }
220
221 return mbox[6];
222 }
223
bcm283x_mbox_clock_get_state(int id)224 int bcm283x_mbox_clock_get_state(int id)
225 {
226 mbox[0] = 8*4; // length of the message
227 mbox[1] = MBOX_REQUEST; // this is a request message
228
229 mbox[2] = MBOX_TAG_CLOCK_GET_STATE;
230 mbox[3] = 8; // buffer size
231 mbox[4] = 4; // len
232
233 mbox[5] = id; // id
234 mbox[6] = 0;
235
236 mbox[7] = MBOX_TAG_LAST;
237 mbox_call(8, MMU_DISABLE);
238
239 if(mbox[5] != id)
240 {
241 return -1;
242 }
243
244 return (mbox[6] & 0x3);
245 }
246
bcm283x_mbox_clock_set_state(int id,int state)247 int bcm283x_mbox_clock_set_state(int id, int state)
248 {
249 mbox[0] = 8*4; // length of the message
250 mbox[1] = MBOX_REQUEST; // this is a request message
251
252 mbox[2] = MBOX_TAG_CLOCK_SET_STATE;
253 mbox[3] = 8; // buffer size
254 mbox[4] = 8; // len
255
256 mbox[5] = id; // id
257 mbox[6] = state & 0x3;
258
259 mbox[7] = MBOX_TAG_LAST;
260 mbox_call(8, MMU_DISABLE);
261
262 if(mbox[5] != id)
263 {
264 return -1;
265 }
266
267 return (mbox[6] & 0x3);
268 }
269
bcm283x_mbox_clock_get_rate(int id)270 int bcm283x_mbox_clock_get_rate(int id)
271 {
272 mbox[0] = 8*4; // length of the message
273 mbox[1] = MBOX_REQUEST; // this is a request message
274
275 mbox[2] = MBOX_TAG_CLOCK_GET_RATE;
276 mbox[3] = 8; // buffer size
277 mbox[4] = 4; // len
278
279 mbox[5] = id; // id
280 mbox[6] = 0;
281
282 mbox[7] = MBOX_TAG_LAST;
283 mbox_call(8, MMU_DISABLE);
284
285 if(mbox[5] != id)
286 {
287 return -1;
288 }
289
290 return mbox[6];
291 }
292
bcm283x_mbox_clock_set_rate(int id,int rate)293 int bcm283x_mbox_clock_set_rate(int id, int rate)
294 {
295 mbox[0] = 8*4; // length of the message
296 mbox[1] = MBOX_REQUEST; // this is a request message
297
298 mbox[2] = MBOX_TAG_CLOCK_SET_RATE;
299 mbox[3] = 8; // buffer size
300 mbox[4] = 8; // len
301
302 mbox[5] = id; // id
303 mbox[6] = rate;
304
305 mbox[7] = MBOX_TAG_LAST;
306 mbox_call(8, MMU_DISABLE);
307
308 if(mbox[5] != id)
309 {
310 return -1;
311 }
312
313 return mbox[6];
314 }
315
bcm283x_mbox_clock_get_max_rate(int id)316 int bcm283x_mbox_clock_get_max_rate(int id)
317 {
318 mbox[0] = 8*4; // length of the message
319 mbox[1] = MBOX_REQUEST; // this is a request message
320
321 mbox[2] = MBOX_TAG_CLOCK_GET_MAX_RATE;
322 mbox[3] = 8; // buffer size
323 mbox[4] = 4; // len
324
325 mbox[5] = id; // id
326 mbox[6] = 0;
327
328 mbox[7] = MBOX_TAG_LAST;
329 mbox_call(8, MMU_DISABLE);
330
331 if(mbox[5] != id)
332 {
333 return -1;
334 }
335
336 return mbox[6];
337 }
338
bcm283x_mbox_clock_get_min_rate(int id)339 int bcm283x_mbox_clock_get_min_rate(int id)
340 {
341 mbox[0] = 8*4; // length of the message
342 mbox[1] = MBOX_REQUEST; // this is a request message
343
344 mbox[2] = MBOX_TAG_CLOCK_GET_MIN_RATE;
345 mbox[3] = 8; // buffer size
346 mbox[4] = 4; // len
347
348 mbox[5] = id; // id
349 mbox[6] = 0;
350
351 mbox[7] = MBOX_TAG_LAST;
352 mbox_call(8, MMU_DISABLE);
353
354 if(mbox[5] != id)
355 {
356 return -1;
357 }
358
359 return mbox[6];
360 }
361
bcm283x_mbox_power_get_state(int id)362 int bcm283x_mbox_power_get_state(int id)
363 {
364 mbox[0] = 8*4; // length of the message
365 mbox[1] = MBOX_REQUEST; // this is a request message
366
367 mbox[2] = MBOX_TAG_POWER_GET_STATE;
368 mbox[3] = 8; // buffer size
369 mbox[4] = 4; // len
370
371 mbox[5] = id; // id
372 mbox[6] = 0;
373
374 mbox[7] = MBOX_TAG_LAST;
375 mbox_call(8, MMU_DISABLE);
376
377 if(mbox[5] != id)
378 {
379 return -1;
380 }
381
382 return (mbox[6] & 0x3);
383 }
384
bcm283x_mbox_power_set_state(int id,int state)385 int bcm283x_mbox_power_set_state(int id, int state)
386 {
387 mbox[0] = 8*4; // length of the message
388 mbox[1] = MBOX_REQUEST; // this is a request message
389
390 mbox[2] = MBOX_TAG_POWER_SET_STATE;
391 mbox[3] = 8; // buffer size
392 mbox[4] = 8; // len
393
394 mbox[5] = id; // id
395 mbox[6] = state & 0x3;
396
397 mbox[7] = MBOX_TAG_LAST;
398 mbox_call(8, MMU_DISABLE);
399
400 if(mbox[5] != id)
401 {
402 return -1;
403 }
404
405 return (mbox[6] & 0x3);
406 }
407
bcm283x_mbox_temp_get(void)408 int bcm283x_mbox_temp_get(void)
409 {
410 mbox[0] = 8*4; // length of the message
411 mbox[1] = MBOX_REQUEST; // this is a request message
412
413 mbox[2] = MBOX_TAG_TEMP_GET;
414 mbox[3] = 8; // buffer size
415 mbox[4] = 4; // len
416
417 mbox[5] = 0; //id
418 mbox[6] = 0;
419
420 mbox[7] = MBOX_TAG_LAST;
421 mbox_call(8, MMU_DISABLE);
422
423 if(mbox[5] != 0)
424 {
425 return -1;
426 }
427
428 return mbox[6];
429 }
430
bcm283x_mbox_temp_get_max(void)431 int bcm283x_mbox_temp_get_max(void)
432 {
433 mbox[0] = 8*4; // length of the message
434 mbox[1] = MBOX_REQUEST; // this is a request message
435
436 mbox[2] = MBOX_TAG_TEMP_GET_MAX;
437 mbox[3] = 8; // buffer size
438 mbox[4] = 4; // len
439
440 mbox[5] = 0; // id
441 mbox[6] = 0;
442
443 mbox[7] = MBOX_TAG_LAST;
444 mbox_call(8, MMU_DISABLE);
445
446 if(mbox[5] != 0)
447 {
448 return -1;
449 }
450
451 return mbox[6];
452 }
453