Selaa lähdekoodia

add raspi4 mbox driver

bigamgic 4 vuotta sitten
vanhempi
commit
b31fe0a578

+ 3 - 0
bsp/raspberry-pi/raspi4-32/README.md

@@ -68,6 +68,9 @@ msh />
 | 驱动 | 支持情况  |  备注  |
 | ------ | ----  | :------:  |
 | UART | 支持 | UART0,UART2,UART3,UART4,UART5 |
+| GPIO | 支持 | - |
+| SPI | 支持 | SPI0 |
+| MAILBOX | 支持 | - |
 
 ## 5. 联系人信息
 

+ 453 - 0
bsp/raspberry-pi/raspi4-32/driver/mbox.c

@@ -0,0 +1,453 @@
+/*
+ * File      : mbox.c
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-08-29     zdzn           first version
+ * 2020-09-10     bigmagic       add other mbox option
+ */
+
+/* mailbox message buffer */
+#include "mbox.h"
+#include "mmu.h"
+//volatile unsigned int  __attribute__((aligned(16))) mbox[36];
+volatile unsigned int *mbox = (volatile unsigned int *) MBOX_ADDR;
+#define BUS_ADDRESS(phys)	(((phys) & ~0xC0000000)  |  0xC0000000)
+
+/**
+ * Make a mailbox call. Returns 0 on failure, non-zero on success
+ */
+int mbox_call(unsigned char ch, int mmu_enable)
+{
+    unsigned int r = (((MBOX_ADDR)&~0xF) | (ch&0xF));
+    if(mmu_enable)
+        r = BUS_ADDRESS(r);
+    /* wait until we can write to the mailbox */
+    do
+    {
+        asm volatile("nop");
+    } while (*MBOX_STATUS & MBOX_FULL);
+    /* write the address of our message to the mailbox with channel identifier */
+    *MBOX_WRITE = r;
+    /* now wait for the response */
+   // rt_kprintf("mailbox request %x\n",r);
+    while(1)
+    {
+        /* is there a response? */
+        do
+        {
+            asm volatile("nop");
+        } while (*MBOX_STATUS & MBOX_EMPTY);
+        /* is it a response to our message? */
+        if (r == *MBOX_READ){
+            /* is it a valid successful response? */
+        	//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]);
+            return mbox[1] == MBOX_RESPONSE;
+        }
+    }
+    return 0;
+}
+
+int bcm283x_mbox_hardware_get_model(void)
+{
+    mbox[0] = 8*4;                          // length of the message
+    mbox[1] = MBOX_REQUEST;                 // this is a request message
+    
+    mbox[2] = MBOX_TAG_HARDWARE_GET_MODEL;
+    mbox[3] = 4;                            // buffer size
+    mbox[4] = 0;                            // len
+
+    mbox[5] = 0;                            
+    mbox[6] = 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    return mbox[5];
+}
+
+int bcm283x_mbox_hardware_get_revison(void)
+{
+    mbox[0] = 8*4;                          // length of the message
+    mbox[1] = MBOX_REQUEST;                 // this is a request message
+    
+    mbox[2] = MBOX_TAG_HARDWARE_GET_REV;   
+    mbox[3] = 4;                            // buffer size
+    mbox[4] = 0;                            // len
+
+    mbox[5] = 0;                    
+    mbox[6] = 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    return mbox[5];
+}
+
+int bcm283x_mbox_hardware_get_mac_address(uint8_t * mac)
+{
+    mbox[0] = 8*4;                                 // length of the message
+    mbox[1] = MBOX_REQUEST;                        // this is a request message
+    
+    mbox[2] = MBOX_TAG_HARDWARE_GET_MAC_ADDRESS;   
+    mbox[3] = 6;                                   // buffer size
+    mbox[4] = 0;                                   // len
+
+    mbox[5] = 0;                    
+    mbox[6] = 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    char * mac_str = (char *)&mbox[5];
+    mac[0] = mac_str[0];
+    mac[1] = mac_str[1];
+    mac[2] = mac_str[2];
+    mac[3] = mac_str[3];
+    mac[4] = mac_str[4];
+    mac[5] = mac_str[5];
+    return 0;
+}
+
+
+int bcm283x_mbox_hardware_get_serial(rt_uint64_t* sn)
+{
+    mbox[0] = 8*4;                              // length of the message
+    mbox[1] = MBOX_REQUEST;                     // this is a request message
+    
+    mbox[2] = MBOX_TAG_HARDWARE_GET_SERIAL;    
+    mbox[3] = 8;                                // buffer size
+    mbox[4] = 0;                                // len
+
+    mbox[5] = 0;                    
+    mbox[6] = 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    sn = (rt_uint64_t *)&mbox[5];
+
+    return 0;
+}
+
+int bcm283x_mbox_hardware_get_arm_memory(rt_uint32_t * base, rt_uint32_t * size)
+{
+    mbox[0] = 8*4;                                  // length of the message
+    mbox[1] = MBOX_REQUEST;                         // this is a request message
+    
+    mbox[2] = MBOX_TAG_HARDWARE_GET_ARM_MEMORY;   
+    mbox[3] = 8;                                    // buffer size
+    mbox[4] = 0;                                    // len
+
+    mbox[5] = 0;                    
+    mbox[6] = 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    *base = mbox[5];
+    *size = mbox[6];
+    
+    return 0;
+
+}
+
+int bcm283x_mbox_hardware_get_vc_memory(rt_uint32_t * base, rt_uint32_t * size)
+{
+    mbox[0] = 8*4;                               // length of the message
+    mbox[1] = MBOX_REQUEST;                      // this is a request message
+    
+    mbox[2] = MBOX_TAG_HARDWARE_GET_VC_MEMORY;
+    mbox[3] = 8;                                 // buffer size
+    mbox[4] = 0;                                 // len
+
+    mbox[5] = 0;                    
+    mbox[6] = 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    *base = mbox[5];
+    *size = mbox[6];
+    
+    return 0;
+}
+
+int bcm283x_mbox_clock_get_turbo(void)
+{
+    mbox[0] = 8*4;                      // length of the message
+    mbox[1] = MBOX_REQUEST;             // this is a request message
+    
+    mbox[2] = MBOX_TAG_CLOCK_GET_TURBO; 
+    mbox[3] = 8;                        // buffer size
+    mbox[4] = 4;                        // len
+
+    mbox[5] = 0;                        // id
+    mbox[6] = 0;                        // val
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    if(mbox[5] != 0)
+    {
+        return -1;
+    }
+
+    return mbox[6];
+}
+
+int bcm283x_mbox_clock_set_turbo(int level)
+{
+    mbox[0] = 8*4;                      // length of the message
+    mbox[1] = MBOX_REQUEST;             // this is a request message
+    
+    mbox[2] = MBOX_TAG_CLOCK_SET_TURBO;  
+    mbox[3] = 8;                        // buffer size
+    mbox[4] = 8;                        // len
+
+    mbox[5] = 0;                        // id
+    mbox[6] = level ? 1 : 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    if(mbox[5] != 0)
+    {
+        return -1;
+    }
+
+    return mbox[6];
+}
+
+int bcm283x_mbox_clock_get_state(int id)
+{
+    mbox[0] = 8*4;                       // length of the message
+    mbox[1] = MBOX_REQUEST;              // this is a request message
+    
+    mbox[2] = MBOX_TAG_CLOCK_GET_STATE;
+    mbox[3] = 8;                         // buffer size
+    mbox[4] = 4;                         // len
+
+    mbox[5] = id;                        // id
+    mbox[6] = 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    if(mbox[5] != id)
+    {
+        return -1;
+    }
+
+    return (mbox[6] & 0x3);
+}
+
+int bcm283x_mbox_clock_set_state(int id, int state)
+{
+    mbox[0] = 8*4;                      // length of the message
+    mbox[1] = MBOX_REQUEST;             // this is a request message
+    
+    mbox[2] = MBOX_TAG_CLOCK_SET_STATE;
+    mbox[3] = 8;                        // buffer size
+    mbox[4] = 8;                        // len
+
+    mbox[5] = id;                       // id
+    mbox[6] = state & 0x3;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    if(mbox[5] != id)
+    {
+        return -1;
+    }
+
+    return (mbox[6] & 0x3);
+}
+
+int bcm283x_mbox_clock_get_rate(int id)
+{
+    mbox[0] = 8*4;                      // length of the message
+    mbox[1] = MBOX_REQUEST;             // this is a request message
+    
+    mbox[2] = MBOX_TAG_CLOCK_GET_RATE; 
+    mbox[3] = 8;                        // buffer size
+    mbox[4] = 4;                        // len
+
+    mbox[5] = id;                       // id
+    mbox[6] = 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    if(mbox[5] != id)
+    {
+        return -1;
+    }
+
+    return mbox[6];
+}
+
+int bcm283x_mbox_clock_set_rate(int id, int rate)
+{
+    mbox[0] = 8*4;                      // length of the message
+    mbox[1] = MBOX_REQUEST;             // this is a request message
+    
+    mbox[2] = MBOX_TAG_CLOCK_SET_RATE;
+    mbox[3] = 8;                        // buffer size
+    mbox[4] = 8;                        // len
+
+    mbox[5] = id;                       // id
+    mbox[6] = rate;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    if(mbox[5] != id)
+    {
+        return -1;
+    }
+
+    return mbox[6];
+}
+
+int bcm283x_mbox_clock_get_max_rate(int id)
+{
+    mbox[0] = 8*4;                          // length of the message
+    mbox[1] = MBOX_REQUEST;                 // this is a request message
+    
+    mbox[2] = MBOX_TAG_CLOCK_GET_MAX_RATE;
+    mbox[3] = 8;                            // buffer size
+    mbox[4] = 4;                            // len
+
+    mbox[5] = id;                           // id
+    mbox[6] = 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    if(mbox[5] != id)
+    {
+        return -1;
+    }
+
+    return mbox[6];
+}
+
+int bcm283x_mbox_clock_get_min_rate(int id)
+{
+    mbox[0] = 8*4;                          // length of the message
+    mbox[1] = MBOX_REQUEST;                 // this is a request message
+    
+    mbox[2] = MBOX_TAG_CLOCK_GET_MIN_RATE; 
+    mbox[3] = 8;                            // buffer size
+    mbox[4] = 4;                            // len
+
+    mbox[5] = id;                           // id
+    mbox[6] = 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    if(mbox[5] != id)
+    {
+        return -1;
+    }
+
+    return mbox[6];
+}
+
+int bcm283x_mbox_power_get_state(int id)
+{
+    mbox[0] = 8*4;                  // length of the message
+    mbox[1] = MBOX_REQUEST;         // this is a request message
+    
+    mbox[2] = MBOX_TAG_POWER_GET_STATE;
+    mbox[3] = 8;                    // buffer size
+    mbox[4] = 4;                    // len
+
+    mbox[5] = id;                   // id
+    mbox[6] = 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    if(mbox[5] != id)
+    {
+        return -1;
+    }
+
+    return (mbox[6] & 0x3);
+}
+
+int bcm283x_mbox_power_set_state(int id, int state)
+{
+    mbox[0] = 8*4;                  // length of the message
+    mbox[1] = MBOX_REQUEST;         // this is a request message
+    
+    mbox[2] = MBOX_TAG_POWER_SET_STATE;
+    mbox[3] = 8;                    // buffer size
+    mbox[4] = 8;                    // len
+
+    mbox[5] = id;                    // id
+    mbox[6] = state & 0x3;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    if(mbox[5] != id)
+    {
+        return -1;
+    }
+
+    return (mbox[6] & 0x3);
+}
+
+int bcm283x_mbox_temp_get(void)
+{
+    mbox[0] = 8*4;                  // length of the message
+    mbox[1] = MBOX_REQUEST;         // this is a request message
+    
+    mbox[2] = MBOX_TAG_TEMP_GET;
+    mbox[3] = 8;                    // buffer size
+    mbox[4] = 4;                    // len
+
+    mbox[5] = 0;                    //id
+    mbox[6] = 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    if(mbox[5] != 0)
+    {
+        return -1;
+    }
+
+    return mbox[6];
+}
+
+int bcm283x_mbox_temp_get_max(void)
+{
+    mbox[0] = 8*4;                  // length of the message
+    mbox[1] = MBOX_REQUEST;         // this is a request message
+    
+    mbox[2] = MBOX_TAG_TEMP_GET_MAX;
+    mbox[3] = 8;                    // buffer size
+    mbox[4] = 4;                    // len
+
+    mbox[5] = 0;                    // id
+    mbox[6] = 0;
+
+    mbox[7] = MBOX_TAG_LAST;
+    mbox_call(8, MMU_DISABLE);
+
+    if(mbox[5] != 0)
+    {
+        return -1;
+    }
+
+    return mbox[6];
+}

+ 123 - 0
bsp/raspberry-pi/raspi4-32/driver/mbox.h

@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2020-09-10     bigmagic       first version
+ */
+
+#ifndef __MBOX_H__
+#define __MBOX_H__
+
+#include <rtthread.h>
+/* a properly aligned buffer */
+extern volatile unsigned int* mbox;
+
+#define MBOX_REQUEST    0
+
+/* channels */
+#define MBOX_CH_POWER   0
+#define MBOX_CH_FB      1
+#define MBOX_CH_VUART   2
+#define MBOX_CH_VCHIQ   3
+#define MBOX_CH_LEDS    4
+#define MBOX_CH_BTNS    5
+#define MBOX_CH_TOUCH   6
+#define MBOX_CH_COUNT   7
+#define MBOX_CH_PROP    8
+
+/* tags */
+#define MBOX_TAG_SETPOWER       0x28001
+#define MBOX_TAG_SETCLKRATE     0x38002
+#define MBOX_GET_MAC_ADDRESS	0x10003
+#define MBOX_TAG_LAST           0
+
+#define MMIO_BASE       0xFE000000
+#define VIDEOCORE_MBOX  (MMIO_BASE+0x0000B880)
+#define MBOX_READ       ((volatile unsigned int*)(VIDEOCORE_MBOX+0x0))
+#define MBOX_POLL       ((volatile unsigned int*)(VIDEOCORE_MBOX+0x10))
+#define MBOX_SENDER     ((volatile unsigned int*)(VIDEOCORE_MBOX+0x14))
+#define MBOX_STATUS     ((volatile unsigned int*)(VIDEOCORE_MBOX+0x18))
+#define MBOX_CONFIG     ((volatile unsigned int*)(VIDEOCORE_MBOX+0x1C))
+#define MBOX_WRITE      ((volatile unsigned int*)(VIDEOCORE_MBOX+0x20))
+#define MBOX_RESPONSE   0x80000000
+#define MBOX_FULL       0x80000000
+#define MBOX_EMPTY      0x40000000
+
+#define DEVICE_ID_SD_CARD	0
+#define DEVICE_ID_USB_HCD	3
+#define POWER_STATE_OFF		(0 << 0)
+#define POWER_STATE_ON		(1 << 0)
+#define POWER_STATE_WAIT	(1 << 1)
+#define POWER_STATE_NO_DEVICE	(1 << 1)	// in response
+#define MMU_ENABLE 1
+#define MMU_DISABLE 0
+
+/*
+ * raspi hardware info
+ */
+enum {
+    MBOX_TAG_HARDWARE_GET_MODEL         = 0x00010001,
+    MBOX_TAG_HARDWARE_GET_REV           = 0x00010002,
+    MBOX_TAG_HARDWARE_GET_MAC_ADDRESS   = 0x00010003,
+    MBOX_TAG_HARDWARE_GET_SERIAL        = 0x00010004,
+    MBOX_TAG_HARDWARE_GET_ARM_MEMORY    = 0x00010005,
+    MBOX_TAG_HARDWARE_GET_VC_MEMORY     = 0x00010006,
+    MBOX_TAG_HARDWARE_GET_CLOCKS        = 0x00010007,
+};
+
+/*
+ * raspi clock
+ */
+enum {
+    MBOX_TAG_CLOCK_GET_TURBO    = 0x00030009,
+    MBOX_TAG_CLOCK_SET_TURBO    = 0x00038009,
+    MBOX_TAG_CLOCK_GET_STATE    = 0x00030001,
+    MBOX_TAG_CLOCK_SET_STATE    = 0x00038001,
+    MBOX_TAG_CLOCK_GET_RATE     = 0x00030002,
+    MBOX_TAG_CLOCK_SET_RATE     = 0x00038002,
+    MBOX_TAG_CLOCK_GET_MAX_RATE = 0x00030004,
+    MBOX_TAG_CLOCK_GET_MIN_RATE = 0x00030007,
+};
+
+/*
+ * raspi power
+ */
+enum {
+    MBOX_TAG_POWER_GET_STATE    = 0x00020001,
+    MBOX_TAG_POWER_SET_STATE    = 0x00028001,
+};
+
+/*
+ * raspi temperature
+ */
+enum {
+    MBOX_TAG_TEMP_GET       = 0x00030006,
+    MBOX_TAG_TEMP_GET_MAX   = 0x0003000A,
+};
+
+#define MBOX_ADDR 0xc00000
+
+int mbox_call(unsigned char ch, int mmu_enable);
+int bcm283x_mbox_hardware_get_model(void);
+int bcm283x_mbox_hardware_get_revison(void);
+int bcm283x_mbox_hardware_get_mac_address(uint8_t * mac);
+int bcm283x_mbox_hardware_get_serial(rt_uint64_t* sn);
+int bcm283x_mbox_hardware_get_arm_memory(rt_uint32_t * base, rt_uint32_t * size);
+int bcm283x_mbox_hardware_get_vc_memory(rt_uint32_t * base, rt_uint32_t * size);
+int bcm283x_mbox_clock_get_turbo(void);
+int bcm283x_mbox_clock_set_turbo(int level);
+int bcm283x_mbox_clock_get_state(int id);
+int bcm283x_mbox_clock_set_state(int id, int state);
+int bcm283x_mbox_clock_get_rate(int id);
+int bcm283x_mbox_clock_set_rate(int id, int rate);
+int bcm283x_mbox_clock_get_max_rate(int id);
+int bcm283x_mbox_clock_get_min_rate(int id);
+int bcm283x_mbox_power_get_state(int id);
+int bcm283x_mbox_power_set_state(int id, int state);
+int bcm283x_mbox_temp_get(void);
+int bcm283x_mbox_temp_get_max(void);
+
+#endif