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