Skip to content

Commit c97f33d

Browse files
committed
add raspi4 hdmi driver
1 parent 67b6177 commit c97f33d

File tree

5 files changed

+427
-12
lines changed

5 files changed

+427
-12
lines changed

bsp/raspberry-pi/raspi4-32/driver/board.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919

2020
struct mem_desc platform_mem_desc[] = {
2121
{0x0, 0x6400000, 0x0, NORMAL_MEM},
22-
{0xFE000000, 0xFE400000, 0xFE000000, DEVICE_MEM},//uart gpio
23-
{0xFF800000, 0xFFA00000, 0xFF800000, DEVICE_MEM} //gic
22+
{0x8000000, 0x8100000, 0x8000000, DEVICE_MEM}, //mbox msg
23+
{0x0EA00000, 0x0EE00000, 0x0EA00000, DEVICE_MEM}, //framebuffer
24+
{0xFE000000, 0xFE400000, 0xFE000000, DEVICE_MEM}, //peripheral
25+
{0xFF800000, 0xFFA00000, 0xFF800000, DEVICE_MEM} //gic
2426
};
2527

2628
const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc)/sizeof(platform_mem_desc[0]);
Lines changed: 307 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,307 @@
1+
/*
2+
* Copyright (c) 2006-2020, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2020-10-26 bigmagic first version
9+
*/
10+
11+
#include <stdint.h>
12+
#include <rtthread.h>
13+
#include "mbox.h"
14+
#include "drv_hdmi.h"
15+
16+
#define LCD_WIDTH (800)
17+
#define LCD_HEIGHT (480)
18+
#define LCD_DEPTH (32)
19+
#define LCD_BPP (32)
20+
21+
#define TAG_ALLOCATE_BUFFER 0x00040001
22+
#define TAG_SET_PHYS_WIDTH_HEIGHT 0x00048003
23+
#define TAG_SET_VIRT_WIDTH_HEIGHT 0x00048004
24+
#define TAG_SET_DEPTH 0x00048005
25+
#define TAG_SET_PIXEL_ORDER 0x00048006
26+
#define TAG_GET_PITCH 0x00040008
27+
#define TAG_SET_VIRT_OFFSET 0x00048009
28+
#define TAG_END 0x00000000
29+
30+
31+
enum {
32+
MBOX_TAG_FB_GET_GPIOVIRT = 0x00040010,
33+
MBOX_TAG_FB_ALLOCATE_BUFFER = 0x00040001,
34+
MBOX_TAG_FB_RELEASE_BUFFER = 0x00048001,
35+
MBOX_TAG_FB_BLANK_SCREEN = 0x00040002,
36+
MBOX_TAG_FB_GET_PHYS_WH = 0x00040003,
37+
MBOX_TAG_FB_TEST_PHYS_WH = 0x00044003,
38+
MBOX_TAG_FB_SET_PHYS_WH = 0x00048003,
39+
MBOX_TAG_FB_GET_VIRT_WH = 0x00040004,
40+
MBOX_TAG_FB_TEST_VIRT_WH = 0x00044004,
41+
MBOX_TAG_FB_SET_VIRT_WH = 0x00048004,
42+
MBOX_TAG_FB_GET_DEPTH = 0x00040005,
43+
MBOX_TAG_FB_TEST_DEPTH = 0x00044005,
44+
MBOX_TAG_FB_SET_DEPTH = 0x00048005,
45+
MBOX_TAG_FB_GET_PIXEL_ORDER = 0x00040006,
46+
MBOX_TAG_FB_TEST_PIXEL_ORDER = 0x00044006,
47+
MBOX_TAG_FB_SET_PIXEL_ORDER = 0x00048006,
48+
MBOX_TAG_FB_GET_ALPHA_MODE = 0x00040007,
49+
MBOX_TAG_FB_TEST_ALPHA_MODE = 0x00044007,
50+
MBOX_TAG_FB_SET_ALPHA_MODE = 0x00048007,
51+
MBOX_TAG_FB_GET_PITCH = 0x00040008,
52+
MBOX_TAG_FB_GET_VIRT_OFFSET = 0x00040009,
53+
MBOX_TAG_FB_TEST_VIRT_OFFSET = 0x00044009,
54+
MBOX_TAG_FB_SET_VIRT_OFFSET = 0x00048009,
55+
MBOX_TAG_FB_GET_OVERSCAN = 0x0004000a,
56+
MBOX_TAG_FB_TEST_OVERSCAN = 0x0004400a,
57+
MBOX_TAG_FB_SET_OVERSCAN = 0x0004800a,
58+
MBOX_TAG_FB_GET_PALETTE = 0x0004000b,
59+
MBOX_TAG_FB_TEST_PALETTE = 0x0004400b,
60+
MBOX_TAG_FB_SET_PALETTE = 0x0004800b,
61+
};
62+
63+
#define LCD_DEVICE(dev) (struct rt_hdmi_fb_device*)(dev)
64+
65+
static struct rt_hdmi_fb_device _hdmi;
66+
67+
typedef rt_uint16_t color_t;
68+
69+
rt_err_t hdmi_fb_open(rt_device_t dev, rt_uint16_t oflag)
70+
{
71+
return RT_EOK;
72+
}
73+
74+
rt_err_t hdmi_fb_close(rt_device_t dev)
75+
{
76+
return RT_EOK;
77+
}
78+
79+
rt_size_t hdmi_fb_read(rt_device_t dev, rt_off_t pos, void *buf, rt_size_t size)
80+
{
81+
return 0;
82+
}
83+
84+
rt_size_t hdmi_fb_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
85+
{
86+
return size;
87+
}
88+
89+
rt_err_t hdmi_fb_control(rt_device_t dev, int cmd, void *args)
90+
{
91+
struct rt_hdmi_fb_device *lcd = LCD_DEVICE(dev);
92+
switch (cmd)
93+
{
94+
case RTGRAPHIC_CTRL_RECT_UPDATE:
95+
{
96+
struct rt_device_rect_info *info = (struct rt_device_rect_info*)args;
97+
info = info;
98+
}
99+
break;
100+
101+
case RTGRAPHIC_CTRL_GET_INFO:
102+
{
103+
struct rt_device_graphic_info* info = (struct rt_device_graphic_info*)args;
104+
105+
RT_ASSERT(info != RT_NULL);
106+
info->pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB888;
107+
info->bits_per_pixel= LCD_DEPTH;
108+
info->width = lcd->width;
109+
info->height = lcd->height;
110+
info->framebuffer = lcd->fb;
111+
}
112+
break;
113+
}
114+
return RT_EOK;
115+
}
116+
117+
#ifdef RT_USING_DEVICE_OPS
118+
const static struct rt_device_ops hdmi_fb_ops =
119+
{
120+
RT_NULL,
121+
hdmi_fb_open,
122+
hdmi_fb_close,
123+
hdmi_fb_read,
124+
hdmi_fb_write,
125+
hdmi_fb_control,
126+
};
127+
#endif
128+
129+
rt_err_t rt_hdmi_fb_device_init(struct rt_hdmi_fb_device *hdmi_fb, const char *name)
130+
{
131+
struct rt_device *device;
132+
RT_ASSERT(hdmi_fb != RT_NULL);
133+
134+
device = &hdmi_fb->parent;
135+
136+
/* set device type */
137+
device->type = RT_Device_Class_Graphic;
138+
/* initialize device interface */
139+
#ifdef RT_USING_DEVICE_OPS
140+
device->ops = &hdmi_fb_ops;
141+
#else
142+
device->init = RT_NULL;
143+
device->open = hdmi_fb_open;
144+
device->close = hdmi_fb_close;
145+
device->read = hdmi_fb_read;
146+
device->write = hdmi_fb_write;
147+
device->control = hdmi_fb_control;
148+
#endif
149+
150+
/* register to device manager */
151+
rt_device_register(device, name, RT_DEVICE_FLAG_RDWR);
152+
153+
return RT_EOK;
154+
}
155+
156+
rt_uint32_t bcm271x_mbox_fb_get_gpiovirt(void)
157+
{
158+
mbox[0] = 8*4; // length of the message
159+
mbox[1] = MBOX_REQUEST; // this is a request message
160+
161+
mbox[2] = MBOX_TAG_FB_GET_GPIOVIRT;
162+
mbox[3] = 4; // buffer size
163+
mbox[4] = 0; // len
164+
165+
mbox[5] = 0; // id
166+
mbox[6] = 0;
167+
168+
mbox[7] = MBOX_TAG_LAST;
169+
mbox_call(8, MMU_DISABLE);
170+
return (mbox[5] & 0x3fffffff);
171+
}
172+
173+
rt_uint32_t bcm271x_mbox_fb_get_pitch(void)
174+
{
175+
mbox[0] = 8*4; // length of the message
176+
mbox[1] = MBOX_REQUEST; // this is a request message
177+
178+
mbox[2] = MBOX_TAG_FB_GET_PITCH;
179+
mbox[3] = 4; // buffer size
180+
mbox[4] = 0; // len
181+
182+
mbox[5] = 0; // id
183+
mbox[6] = 0;
184+
185+
mbox[7] = MBOX_TAG_LAST;
186+
mbox_call(8, MMU_DISABLE);
187+
return mbox[5];
188+
}
189+
190+
void bcm271x_mbox_fb_set_porder(int rgb)
191+
{
192+
mbox[0] = 8*4; // length of the message
193+
mbox[1] = MBOX_REQUEST; // this is a request message
194+
195+
mbox[2] = MBOX_TAG_FB_SET_PIXEL_ORDER;
196+
mbox[3] = 4; // buffer size
197+
mbox[4] = 4; // len
198+
199+
mbox[5] = rgb; // id
200+
mbox[6] = 0;
201+
202+
mbox[7] = MBOX_TAG_LAST;
203+
mbox_call(8, MMU_DISABLE);
204+
}
205+
206+
void bcm271x_mbox_fb_setoffset(int xoffset, int yoffset)
207+
{
208+
mbox[0] = 8*4; // length of the message
209+
mbox[1] = MBOX_REQUEST; // this is a request message
210+
211+
mbox[2] = MBOX_TAG_FB_SET_VIRT_OFFSET;
212+
mbox[3] = 8; // buffer size
213+
mbox[4] = 8; // len
214+
215+
mbox[5] = xoffset; // id
216+
mbox[6] = yoffset;
217+
218+
mbox[7] = MBOX_TAG_LAST;
219+
mbox_call(8, MMU_DISABLE);
220+
}
221+
222+
223+
void bcm271x_mbox_fb_setalpha(int alpha)
224+
{
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_FB_SET_ALPHA_MODE;
230+
mbox[3] = 4; // buffer size
231+
mbox[4] = 4; // len
232+
233+
mbox[5] = alpha; // id
234+
mbox[6] = 0;
235+
236+
mbox[7] = MBOX_TAG_LAST;
237+
mbox_call(8, MMU_DISABLE);
238+
}
239+
240+
void *bcm271x_mbox_fb_alloc(int width, int height, int bpp, int nrender)
241+
{
242+
mbox[0] = 4 * 35;
243+
mbox[1] = MBOX_REQUEST;
244+
245+
mbox[2] = TAG_ALLOCATE_BUFFER;//get framebuffer, gets alignment on request
246+
mbox[3] = 8; //size
247+
mbox[4] = 4; //len
248+
mbox[5] = 4096; //The design of MBOX driver forces us to give the virtual address 0x3C100000
249+
mbox[6] = 0; //FrameBufferInfo.size
250+
251+
mbox[7] = TAG_SET_PHYS_WIDTH_HEIGHT;
252+
mbox[8] = 8;
253+
mbox[9] = 8;
254+
mbox[10] = width;
255+
mbox[11] = height;
256+
257+
mbox[12] = TAG_SET_VIRT_WIDTH_HEIGHT;
258+
mbox[13] = 8;
259+
mbox[14] = 8;
260+
mbox[15] = width;
261+
mbox[16] = height * nrender;
262+
263+
mbox[17] = TAG_SET_DEPTH;
264+
mbox[18] = 4;
265+
mbox[19] = 4;
266+
mbox[20] = bpp;
267+
268+
mbox[21] = TAG_SET_PIXEL_ORDER;
269+
mbox[22] = 4;
270+
mbox[23] = 0;
271+
mbox[24] = 0; //RGB, not BGR preferably
272+
273+
mbox[25] = TAG_GET_PITCH;
274+
mbox[26] = 4;
275+
mbox[27] = 0;
276+
mbox[28] = 0;
277+
278+
mbox[29] = TAG_SET_VIRT_OFFSET;
279+
mbox[30] = 8;
280+
mbox[31] = 8;
281+
mbox[32] = 0;
282+
mbox[33] = 0;
283+
284+
mbox[34] = TAG_END;
285+
286+
mbox_call(8, MMU_DISABLE);
287+
return (void *)((rt_uint32_t)(mbox[5] & 0x3fffffff));
288+
}
289+
290+
int hdmi_fb_init(void)
291+
{
292+
_hdmi.fb = (rt_uint8_t *)bcm271x_mbox_fb_alloc(LCD_WIDTH, LCD_HEIGHT, LCD_BPP, 1);
293+
bcm271x_mbox_fb_setoffset(0, 0);
294+
bcm271x_mbox_fb_set_porder(0);
295+
_hdmi.width = LCD_WIDTH;
296+
_hdmi.height = LCD_HEIGHT;
297+
_hdmi.depth = LCD_DEPTH;
298+
_hdmi.pitch = 0;
299+
_hdmi.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB888;
300+
301+
//rt_kprintf("_hdmi.fb is %p\n", _hdmi.fb);
302+
rt_hdmi_fb_device_init(&_hdmi, "lcd");
303+
304+
return 0;
305+
}
306+
307+
INIT_DEVICE_EXPORT(hdmi_fb_init);
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright (c) 2006-2020, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2020-10-26 bigmagic first version
9+
*/
10+
#ifndef __DRV_HDMI_H__
11+
#define __DRV_HDMI_H__
12+
13+
#define RGB(r, g, b) ((((r))<<16) | (((g))<<8) | ((b)))
14+
15+
struct rt_hdmi_fb_device
16+
{
17+
struct rt_device parent;
18+
19+
rt_uint32_t width;
20+
rt_uint32_t height;
21+
rt_uint32_t depth;
22+
rt_uint32_t pitch;
23+
rt_uint32_t pixel_format;
24+
25+
rt_uint8_t *fb;
26+
};
27+
#endif/* __DRV_HDMI_H__ */

0 commit comments

Comments
 (0)