add raspi4 hdmi driver
This commit is contained in:
parent
67b6177de7
commit
c97f33d11d
@ -19,8 +19,10 @@
|
||||
|
||||
struct mem_desc platform_mem_desc[] = {
|
||||
{0x0, 0x6400000, 0x0, NORMAL_MEM},
|
||||
{0xFE000000, 0xFE400000, 0xFE000000, DEVICE_MEM},//uart gpio
|
||||
{0xFF800000, 0xFFA00000, 0xFF800000, DEVICE_MEM} //gic
|
||||
{0x8000000, 0x8100000, 0x8000000, DEVICE_MEM}, //mbox msg
|
||||
{0x0EA00000, 0x0EE00000, 0x0EA00000, DEVICE_MEM}, //framebuffer
|
||||
{0xFE000000, 0xFE400000, 0xFE000000, DEVICE_MEM}, //peripheral
|
||||
{0xFF800000, 0xFFA00000, 0xFF800000, DEVICE_MEM} //gic
|
||||
};
|
||||
|
||||
const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc)/sizeof(platform_mem_desc[0]);
|
||||
|
307
bsp/raspberry-pi/raspi4-32/driver/drv_hdmi.c
Normal file
307
bsp/raspberry-pi/raspi4-32/driver/drv_hdmi.c
Normal file
@ -0,0 +1,307 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2020, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2020-10-26 bigmagic first version
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <rtthread.h>
|
||||
#include "mbox.h"
|
||||
#include "drv_hdmi.h"
|
||||
|
||||
#define LCD_WIDTH (800)
|
||||
#define LCD_HEIGHT (480)
|
||||
#define LCD_DEPTH (32)
|
||||
#define LCD_BPP (32)
|
||||
|
||||
#define TAG_ALLOCATE_BUFFER 0x00040001
|
||||
#define TAG_SET_PHYS_WIDTH_HEIGHT 0x00048003
|
||||
#define TAG_SET_VIRT_WIDTH_HEIGHT 0x00048004
|
||||
#define TAG_SET_DEPTH 0x00048005
|
||||
#define TAG_SET_PIXEL_ORDER 0x00048006
|
||||
#define TAG_GET_PITCH 0x00040008
|
||||
#define TAG_SET_VIRT_OFFSET 0x00048009
|
||||
#define TAG_END 0x00000000
|
||||
|
||||
|
||||
enum {
|
||||
MBOX_TAG_FB_GET_GPIOVIRT = 0x00040010,
|
||||
MBOX_TAG_FB_ALLOCATE_BUFFER = 0x00040001,
|
||||
MBOX_TAG_FB_RELEASE_BUFFER = 0x00048001,
|
||||
MBOX_TAG_FB_BLANK_SCREEN = 0x00040002,
|
||||
MBOX_TAG_FB_GET_PHYS_WH = 0x00040003,
|
||||
MBOX_TAG_FB_TEST_PHYS_WH = 0x00044003,
|
||||
MBOX_TAG_FB_SET_PHYS_WH = 0x00048003,
|
||||
MBOX_TAG_FB_GET_VIRT_WH = 0x00040004,
|
||||
MBOX_TAG_FB_TEST_VIRT_WH = 0x00044004,
|
||||
MBOX_TAG_FB_SET_VIRT_WH = 0x00048004,
|
||||
MBOX_TAG_FB_GET_DEPTH = 0x00040005,
|
||||
MBOX_TAG_FB_TEST_DEPTH = 0x00044005,
|
||||
MBOX_TAG_FB_SET_DEPTH = 0x00048005,
|
||||
MBOX_TAG_FB_GET_PIXEL_ORDER = 0x00040006,
|
||||
MBOX_TAG_FB_TEST_PIXEL_ORDER = 0x00044006,
|
||||
MBOX_TAG_FB_SET_PIXEL_ORDER = 0x00048006,
|
||||
MBOX_TAG_FB_GET_ALPHA_MODE = 0x00040007,
|
||||
MBOX_TAG_FB_TEST_ALPHA_MODE = 0x00044007,
|
||||
MBOX_TAG_FB_SET_ALPHA_MODE = 0x00048007,
|
||||
MBOX_TAG_FB_GET_PITCH = 0x00040008,
|
||||
MBOX_TAG_FB_GET_VIRT_OFFSET = 0x00040009,
|
||||
MBOX_TAG_FB_TEST_VIRT_OFFSET = 0x00044009,
|
||||
MBOX_TAG_FB_SET_VIRT_OFFSET = 0x00048009,
|
||||
MBOX_TAG_FB_GET_OVERSCAN = 0x0004000a,
|
||||
MBOX_TAG_FB_TEST_OVERSCAN = 0x0004400a,
|
||||
MBOX_TAG_FB_SET_OVERSCAN = 0x0004800a,
|
||||
MBOX_TAG_FB_GET_PALETTE = 0x0004000b,
|
||||
MBOX_TAG_FB_TEST_PALETTE = 0x0004400b,
|
||||
MBOX_TAG_FB_SET_PALETTE = 0x0004800b,
|
||||
};
|
||||
|
||||
#define LCD_DEVICE(dev) (struct rt_hdmi_fb_device*)(dev)
|
||||
|
||||
static struct rt_hdmi_fb_device _hdmi;
|
||||
|
||||
typedef rt_uint16_t color_t;
|
||||
|
||||
rt_err_t hdmi_fb_open(rt_device_t dev, rt_uint16_t oflag)
|
||||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
rt_err_t hdmi_fb_close(rt_device_t dev)
|
||||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
rt_size_t hdmi_fb_read(rt_device_t dev, rt_off_t pos, void *buf, rt_size_t size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
rt_size_t hdmi_fb_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
rt_err_t hdmi_fb_control(rt_device_t dev, int cmd, void *args)
|
||||
{
|
||||
struct rt_hdmi_fb_device *lcd = LCD_DEVICE(dev);
|
||||
switch (cmd)
|
||||
{
|
||||
case RTGRAPHIC_CTRL_RECT_UPDATE:
|
||||
{
|
||||
struct rt_device_rect_info *info = (struct rt_device_rect_info*)args;
|
||||
info = info;
|
||||
}
|
||||
break;
|
||||
|
||||
case RTGRAPHIC_CTRL_GET_INFO:
|
||||
{
|
||||
struct rt_device_graphic_info* info = (struct rt_device_graphic_info*)args;
|
||||
|
||||
RT_ASSERT(info != RT_NULL);
|
||||
info->pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB888;
|
||||
info->bits_per_pixel= LCD_DEPTH;
|
||||
info->width = lcd->width;
|
||||
info->height = lcd->height;
|
||||
info->framebuffer = lcd->fb;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
const static struct rt_device_ops hdmi_fb_ops =
|
||||
{
|
||||
RT_NULL,
|
||||
hdmi_fb_open,
|
||||
hdmi_fb_close,
|
||||
hdmi_fb_read,
|
||||
hdmi_fb_write,
|
||||
hdmi_fb_control,
|
||||
};
|
||||
#endif
|
||||
|
||||
rt_err_t rt_hdmi_fb_device_init(struct rt_hdmi_fb_device *hdmi_fb, const char *name)
|
||||
{
|
||||
struct rt_device *device;
|
||||
RT_ASSERT(hdmi_fb != RT_NULL);
|
||||
|
||||
device = &hdmi_fb->parent;
|
||||
|
||||
/* set device type */
|
||||
device->type = RT_Device_Class_Graphic;
|
||||
/* initialize device interface */
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
device->ops = &hdmi_fb_ops;
|
||||
#else
|
||||
device->init = RT_NULL;
|
||||
device->open = hdmi_fb_open;
|
||||
device->close = hdmi_fb_close;
|
||||
device->read = hdmi_fb_read;
|
||||
device->write = hdmi_fb_write;
|
||||
device->control = hdmi_fb_control;
|
||||
#endif
|
||||
|
||||
/* register to device manager */
|
||||
rt_device_register(device, name, RT_DEVICE_FLAG_RDWR);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
rt_uint32_t bcm271x_mbox_fb_get_gpiovirt(void)
|
||||
{
|
||||
mbox[0] = 8*4; // length of the message
|
||||
mbox[1] = MBOX_REQUEST; // this is a request message
|
||||
|
||||
mbox[2] = MBOX_TAG_FB_GET_GPIOVIRT;
|
||||
mbox[3] = 4; // buffer size
|
||||
mbox[4] = 0; // len
|
||||
|
||||
mbox[5] = 0; // id
|
||||
mbox[6] = 0;
|
||||
|
||||
mbox[7] = MBOX_TAG_LAST;
|
||||
mbox_call(8, MMU_DISABLE);
|
||||
return (mbox[5] & 0x3fffffff);
|
||||
}
|
||||
|
||||
rt_uint32_t bcm271x_mbox_fb_get_pitch(void)
|
||||
{
|
||||
mbox[0] = 8*4; // length of the message
|
||||
mbox[1] = MBOX_REQUEST; // this is a request message
|
||||
|
||||
mbox[2] = MBOX_TAG_FB_GET_PITCH;
|
||||
mbox[3] = 4; // buffer size
|
||||
mbox[4] = 0; // len
|
||||
|
||||
mbox[5] = 0; // id
|
||||
mbox[6] = 0;
|
||||
|
||||
mbox[7] = MBOX_TAG_LAST;
|
||||
mbox_call(8, MMU_DISABLE);
|
||||
return mbox[5];
|
||||
}
|
||||
|
||||
void bcm271x_mbox_fb_set_porder(int rgb)
|
||||
{
|
||||
mbox[0] = 8*4; // length of the message
|
||||
mbox[1] = MBOX_REQUEST; // this is a request message
|
||||
|
||||
mbox[2] = MBOX_TAG_FB_SET_PIXEL_ORDER;
|
||||
mbox[3] = 4; // buffer size
|
||||
mbox[4] = 4; // len
|
||||
|
||||
mbox[5] = rgb; // id
|
||||
mbox[6] = 0;
|
||||
|
||||
mbox[7] = MBOX_TAG_LAST;
|
||||
mbox_call(8, MMU_DISABLE);
|
||||
}
|
||||
|
||||
void bcm271x_mbox_fb_setoffset(int xoffset, int yoffset)
|
||||
{
|
||||
mbox[0] = 8*4; // length of the message
|
||||
mbox[1] = MBOX_REQUEST; // this is a request message
|
||||
|
||||
mbox[2] = MBOX_TAG_FB_SET_VIRT_OFFSET;
|
||||
mbox[3] = 8; // buffer size
|
||||
mbox[4] = 8; // len
|
||||
|
||||
mbox[5] = xoffset; // id
|
||||
mbox[6] = yoffset;
|
||||
|
||||
mbox[7] = MBOX_TAG_LAST;
|
||||
mbox_call(8, MMU_DISABLE);
|
||||
}
|
||||
|
||||
|
||||
void bcm271x_mbox_fb_setalpha(int alpha)
|
||||
{
|
||||
|
||||
mbox[0] = 8*4; // length of the message
|
||||
mbox[1] = MBOX_REQUEST; // this is a request message
|
||||
|
||||
mbox[2] = MBOX_TAG_FB_SET_ALPHA_MODE;
|
||||
mbox[3] = 4; // buffer size
|
||||
mbox[4] = 4; // len
|
||||
|
||||
mbox[5] = alpha; // id
|
||||
mbox[6] = 0;
|
||||
|
||||
mbox[7] = MBOX_TAG_LAST;
|
||||
mbox_call(8, MMU_DISABLE);
|
||||
}
|
||||
|
||||
void *bcm271x_mbox_fb_alloc(int width, int height, int bpp, int nrender)
|
||||
{
|
||||
mbox[0] = 4 * 35;
|
||||
mbox[1] = MBOX_REQUEST;
|
||||
|
||||
mbox[2] = TAG_ALLOCATE_BUFFER;//get framebuffer, gets alignment on request
|
||||
mbox[3] = 8; //size
|
||||
mbox[4] = 4; //len
|
||||
mbox[5] = 4096; //The design of MBOX driver forces us to give the virtual address 0x3C100000
|
||||
mbox[6] = 0; //FrameBufferInfo.size
|
||||
|
||||
mbox[7] = TAG_SET_PHYS_WIDTH_HEIGHT;
|
||||
mbox[8] = 8;
|
||||
mbox[9] = 8;
|
||||
mbox[10] = width;
|
||||
mbox[11] = height;
|
||||
|
||||
mbox[12] = TAG_SET_VIRT_WIDTH_HEIGHT;
|
||||
mbox[13] = 8;
|
||||
mbox[14] = 8;
|
||||
mbox[15] = width;
|
||||
mbox[16] = height * nrender;
|
||||
|
||||
mbox[17] = TAG_SET_DEPTH;
|
||||
mbox[18] = 4;
|
||||
mbox[19] = 4;
|
||||
mbox[20] = bpp;
|
||||
|
||||
mbox[21] = TAG_SET_PIXEL_ORDER;
|
||||
mbox[22] = 4;
|
||||
mbox[23] = 0;
|
||||
mbox[24] = 0; //RGB, not BGR preferably
|
||||
|
||||
mbox[25] = TAG_GET_PITCH;
|
||||
mbox[26] = 4;
|
||||
mbox[27] = 0;
|
||||
mbox[28] = 0;
|
||||
|
||||
mbox[29] = TAG_SET_VIRT_OFFSET;
|
||||
mbox[30] = 8;
|
||||
mbox[31] = 8;
|
||||
mbox[32] = 0;
|
||||
mbox[33] = 0;
|
||||
|
||||
mbox[34] = TAG_END;
|
||||
|
||||
mbox_call(8, MMU_DISABLE);
|
||||
return (void *)((rt_uint32_t)(mbox[5] & 0x3fffffff));
|
||||
}
|
||||
|
||||
int hdmi_fb_init(void)
|
||||
{
|
||||
_hdmi.fb = (rt_uint8_t *)bcm271x_mbox_fb_alloc(LCD_WIDTH, LCD_HEIGHT, LCD_BPP, 1);
|
||||
bcm271x_mbox_fb_setoffset(0, 0);
|
||||
bcm271x_mbox_fb_set_porder(0);
|
||||
_hdmi.width = LCD_WIDTH;
|
||||
_hdmi.height = LCD_HEIGHT;
|
||||
_hdmi.depth = LCD_DEPTH;
|
||||
_hdmi.pitch = 0;
|
||||
_hdmi.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB888;
|
||||
|
||||
//rt_kprintf("_hdmi.fb is %p\n", _hdmi.fb);
|
||||
rt_hdmi_fb_device_init(&_hdmi, "lcd");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
INIT_DEVICE_EXPORT(hdmi_fb_init);
|
27
bsp/raspberry-pi/raspi4-32/driver/drv_hdmi.h
Normal file
27
bsp/raspberry-pi/raspi4-32/driver/drv_hdmi.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2020, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2020-10-26 bigmagic first version
|
||||
*/
|
||||
#ifndef __DRV_HDMI_H__
|
||||
#define __DRV_HDMI_H__
|
||||
|
||||
#define RGB(r, g, b) ((((r))<<16) | (((g))<<8) | ((b)))
|
||||
|
||||
struct rt_hdmi_fb_device
|
||||
{
|
||||
struct rt_device parent;
|
||||
|
||||
rt_uint32_t width;
|
||||
rt_uint32_t height;
|
||||
rt_uint32_t depth;
|
||||
rt_uint32_t pitch;
|
||||
rt_uint32_t pixel_format;
|
||||
|
||||
rt_uint8_t *fb;
|
||||
};
|
||||
#endif/* __DRV_HDMI_H__ */
|
@ -49,6 +49,52 @@ int mbox_call(unsigned char ch, int mmu_enable)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bcm271x_notify_reboot(void)
|
||||
{
|
||||
mbox[0] = 7*4; // length of the message
|
||||
mbox[1] = MBOX_REQUEST; // this is a request message
|
||||
mbox[2] = MBOX_TAG_NOTIFY_REBOOT; // (the tag id)
|
||||
mbox[3] = 0x00000004; // length + 4
|
||||
mbox[4] = 0x00000000; // size of the data
|
||||
mbox[5] = 0x00000000; // request
|
||||
|
||||
mbox[6] = MBOX_TAG_LAST;
|
||||
mbox_call(8, MMU_DISABLE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bcm271x_notify_xhci_reset(void)
|
||||
{
|
||||
mbox[0] = 7*4; // length of the message
|
||||
mbox[1] = MBOX_REQUEST; // this is a request message
|
||||
mbox[2] = MBOX_TAG_NOTIFY_XHCI_RESET; // (the tag id)
|
||||
mbox[3] = 0x00000004; // length + 4
|
||||
mbox[4] = 0x00000004; // size of the data
|
||||
mbox[5] = 0x00100000; // request
|
||||
mbox[6] = MBOX_TAG_LAST;
|
||||
mbox_call(8, MMU_DISABLE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bcm271x_gpu_enable(void)
|
||||
{
|
||||
mbox[0] = 12*4; // length of the message
|
||||
mbox[1] = MBOX_REQUEST; // this is a request message
|
||||
|
||||
mbox[2] = MBOX_TAG_CLOCK_SET_RATE;
|
||||
mbox[3] = 0x00000008; // (the tag id)
|
||||
mbox[4] = 0x00000008; // (the tag id)
|
||||
mbox[5] = 5; // V3D
|
||||
mbox[6] = 250 * 1000 * 1000;
|
||||
mbox[7] = MBOX_TAG_ENABLE_QPU; // (the tag id)
|
||||
mbox[8] = 0x00000004; // (size of the buffer)
|
||||
mbox[9] = 0x00000004; // (size of the data)
|
||||
mbox[10] = 0x00000001;
|
||||
mbox[11] = MBOX_TAG_LAST; // end tag
|
||||
mbox_call(8, MMU_DISABLE);
|
||||
return mbox[1];
|
||||
}
|
||||
|
||||
int bcm271x_mbox_hardware_get_model(void)
|
||||
{
|
||||
mbox[0] = 8*4; // length of the message
|
||||
|
@ -35,7 +35,7 @@ extern volatile unsigned int* mbox;
|
||||
/* tags */
|
||||
#define MBOX_TAG_SETPOWER 0x28001
|
||||
#define MBOX_TAG_SETCLKRATE 0x38002
|
||||
#define MBOX_GET_MAC_ADDRESS 0x10003
|
||||
#define MBOX_GET_MAC_ADDRESS 0x10003
|
||||
#define MBOX_TAG_LAST 0
|
||||
|
||||
#define MMIO_BASE 0xFE000000
|
||||
@ -50,14 +50,14 @@ extern volatile unsigned int* mbox;
|
||||
#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
|
||||
#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
|
||||
@ -102,9 +102,42 @@ enum {
|
||||
MBOX_TAG_TEMP_GET_MAX = 0x0003000A,
|
||||
};
|
||||
|
||||
#define MBOX_ADDR 0xc00000
|
||||
/*
|
||||
* raspi Memory
|
||||
*/
|
||||
enum {
|
||||
MBOX_TAG_ALLOCATE_MEMORY = 0x0003000C, // Memory: Allocates Contiguous Memory On The GPU (Response: Handle)
|
||||
MBOX_TAG_LOCK_MEMORY = 0x0003000D, // Memory: Unlock Buffer (Response: Status)
|
||||
MBOX_TAG_UNLOCK_MEMORY = 0x0003000E, // Memory: Unlock Buffer (Response: Status)
|
||||
MBOX_TAG_RELEASE_MEMORY = 0x0003000F, // Memory: Free The Memory Buffer (Response: Status)
|
||||
MBOX_TAG_EXECUTE_CODE = 0x00030010, // Memory: Calls The Function At Given (Bus) Address And With Arguments Given
|
||||
};
|
||||
|
||||
/*
|
||||
* raspi GPU
|
||||
*/
|
||||
enum {
|
||||
MBOX_TAG_EXECUTE_QPU = 0x00030011, // QPU: Calls The QPU Function At Given (Bus) Address And With Arguments Given (Response: Number Of QPUs, Control, No Flush, Timeout In ms)
|
||||
MBOX_TAG_ENABLE_QPU = 0x00030012, // QPU: Enables The QPU (Response: Enable State)
|
||||
};
|
||||
|
||||
/*
|
||||
* raspi HDMI
|
||||
*/
|
||||
#define MBOX_TAG_GET_EDID_BLOCK 0x00030020 // HDMI: Read Specificed EDID Block From Attached HDMI/DVI Device (Response: Block Number, Status, EDID Block (128 Bytes))
|
||||
|
||||
/*
|
||||
* raspi NOTIFY
|
||||
*/
|
||||
#define MBOX_TAG_NOTIFY_REBOOT 0x00030048
|
||||
#define MBOX_TAG_NOTIFY_XHCI_RESET 0x00030058
|
||||
|
||||
#define MBOX_ADDR 0x08000000
|
||||
|
||||
int mbox_call(unsigned char ch, int mmu_enable);
|
||||
int bcm271x_notify_reboot(void);
|
||||
int bcm271x_notify_xhci_reset(void);
|
||||
int bcm271x_gpu_enable(void);
|
||||
int bcm271x_mbox_hardware_get_model(void);
|
||||
int bcm271x_mbox_hardware_get_revison(void);
|
||||
int bcm271x_mbox_hardware_get_mac_address(uint8_t * mac);
|
||||
|
Loading…
x
Reference in New Issue
Block a user