Browse Source

Add BCM2835 (Raspberry Pi) framebuffer and mailbox implementations

Aaron Lindsay 7 years ago
parent
commit
af22b6fe46

+ 69 - 0
devices/bcm2835_mailbox.c

@@ -0,0 +1,69 @@
1
+/*
2
+    Copyright (C) 2012, Aaron Lindsay <aaron@aclindsay.com>
3
+
4
+    This file is part of Aedrix.
5
+
6
+    This program is free software; you can redistribute it and/or modify
7
+    it under the terms of the GNU General Public License as published by
8
+    the Free Software Foundation; either version 2 of the License, or
9
+    (at your option) any later version.
10
+
11
+    This program is distributed in the hope that it will be useful,
12
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+    GNU General Public License for more details.
15
+
16
+    You should have received a copy of the GNU General Public License along
17
+    with this program; if not, write to the Free Software Foundation, Inc.,
18
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
+ */
20
+
21
+#include <types.h>
22
+
23
+/* Mailbox Memory-Mapped Registers */
24
+#define VC_MMU_IO_OFFSET(addr) (addr - 0x7E000000 + 0x20000000)
25
+
26
+#define MBOX0_READ	VC_MMU_IO_OFFSET(0x7E00B880)
27
+/*	MBOX0_READ layout:
28
+	31-4	data	The 28 bits of data sent to the CPU
29
+	3-0	channel	The mailbox channel number from which the data originated */
30
+#define MBOX0_PEEK	VC_MMU_IO_OFFSET(0x7E00B890)	//Read from the mailbox without removing data from it.
31
+#define MBOX0_SENDER	VC_MMU_IO_OFFSET(0x7E00B894)	//Sender ID (bottom 2 bits only)
32
+#define MBOX0_STATUS	VC_MMU_IO_OFFSET(0x7E00B898)
33
+/*	MBOX0_STATUS layout:
34
+	31	full	Set if the mailbox is full, and thus no more data can be written to it.
35
+	30	empty	Set if the mailbox is empty, and thus no more data is available to be read from it.
36
+	29-0		unused? */
37
+#define MBOX0_CONFIG	VC_MMU_IO_OFFSET(0x7E00B89C)
38
+#define MBOX0_WRITE	VC_MMU_IO_OFFSET(0x7E00B8A0)	//also MBOX1_READ?
39
+/*	MBOX0_WRITE layout:
40
+	31-4	data	The 28 bits of data to be sent
41
+	3-0	channel	The mailbox channel to send data to */
42
+
43
+#define MBOX0_STATUS_FULL	0x80000000
44
+#define MBOX0_STATUS_EMPTY	0x40000000
45
+
46
+
47
+uint32 mailbox_read(uint32 channel) {
48
+	uint32 mbox_msg;
49
+	while (1) {
50
+		int i;
51
+		for (i = 0; *(volatile uint32 *)MBOX0_STATUS & MBOX0_STATUS_EMPTY; i++) {
52
+			if (i >= 1<<20)
53
+				return 0xFFFFFFFF;
54
+		}
55
+
56
+		mbox_msg = *(volatile uint32 *)MBOX0_READ;
57
+		if ((mbox_msg & 0xf) == channel)
58
+			return mbox_msg & ~0xf;
59
+	}
60
+} 
61
+
62
+void mailbox_write(uint32 channel, uint32 data) {
63
+	channel &= 0xf;
64
+	data &= ~0xf;
65
+
66
+	while (*(volatile uint32 *)MBOX0_STATUS & MBOX0_STATUS_FULL);
67
+
68
+	*(volatile uint32 *)MBOX0_WRITE = channel | data;
69
+}

+ 94 - 0
devices/bcm2835_videocore.c

@@ -0,0 +1,94 @@
1
+/*
2
+    Copyright (C) 2012, Aaron Lindsay <aaron@aclindsay.com>
3
+
4
+    This file is part of Aedrix.
5
+
6
+    This program is free software; you can redistribute it and/or modify
7
+    it under the terms of the GNU General Public License as published by
8
+    the Free Software Foundation; either version 2 of the License, or
9
+    (at your option) any later version.
10
+
11
+    This program is distributed in the hope that it will be useful,
12
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+    GNU General Public License for more details.
15
+
16
+    You should have received a copy of the GNU General Public License along
17
+    with this program; if not, write to the Free Software Foundation, Inc.,
18
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
+ */
20
+
21
+#include <types.h>
22
+#include <framebuffer.h>
23
+#include <kmalloc.h>
24
+#include <print.h>
25
+#include <devices/bcm2835_mailbox.h>
26
+
27
+struct bcm2835_config {
28
+	uint32 width;
29
+	uint32 height;
30
+	uint32 vwidth;
31
+	uint32 vheight;
32
+	uint32 pitch;
33
+	uint32 color_depth;
34
+	uint32 xoffset;
35
+	uint32 yoffset;
36
+	uint32 fb_base_addr;
37
+	uint32 size;
38
+};
39
+
40
+#define MAILBOX_BUFFER_SIZE (32*4*2)
41
+#define FB_WIDTH 1024
42
+#define FB_HEIGHT 768
43
+
44
+struct fbdev bcm2835_fb_device;
45
+
46
+int bcm2835_videocore_init(struct fb *f, unsigned int color_depth) {
47
+	struct bcm2835_config *cfg;
48
+	uint32 result;
49
+	void *mailbox_buffer_orig, *mailbox_buffer;
50
+
51
+	if (!(mailbox_buffer_orig = kmalloc(MAILBOX_BUFFER_SIZE))) {
52
+		return -1;
53
+	}
54
+
55
+	/* Round mailbox buffer to multiple of 0x10 because the low 4 bits of
56
+	the mailbox are used to send the channel, and therefore can't hold the low 4
57
+	bits of the address */
58
+	if ((uint32)mailbox_buffer_orig & 0xf)
59
+		mailbox_buffer = (void *)((uint32)mailbox_buffer_orig & ~0xf) + 0x10;
60
+	else
61
+		mailbox_buffer = mailbox_buffer_orig;
62
+
63
+	cfg = (struct bcm2835_config *)mailbox_buffer;
64
+	cfg->width = FB_WIDTH;
65
+	cfg->height = FB_HEIGHT;
66
+	cfg->vwidth = FB_WIDTH;
67
+	cfg->vheight = FB_HEIGHT;
68
+	cfg->pitch = 0;
69
+	cfg->color_depth = color_depth;
70
+	cfg->xoffset = 0;
71
+	cfg->yoffset = 0;
72
+	cfg->fb_base_addr = 0;
73
+	cfg->size = 0;
74
+
75
+	mailbox_write(MBOX_FB, (uint32)cfg);
76
+	result = mailbox_read(MBOX_FB);
77
+
78
+	if (result || !cfg->fb_base_addr) {
79
+		print("Error: did not request a proper framebuffer\n");
80
+		return -1;
81
+	}
82
+
83
+	f->device = &bcm2835_fb_device;
84
+	f->device->fbaddr = (void*)cfg->fb_base_addr;
85
+	f->width = cfg->width;
86
+	f->device->pixelwidth = cfg->width;
87
+	f->height = cfg->height;
88
+	f->device->pixelheight = cfg->height;
89
+
90
+	f->color_depth = color_depth;
91
+	f->device->color_depth = color_depth;
92
+
93
+	return 0;
94
+}

+ 3 - 1
devices/kernel.mk

@@ -6,7 +6,9 @@ include $(BASEDIR)/header.mk
6 6
 OBJS_$(d) := $(d)/pl011.o \
7 7
 	$(d)/pl110.o \
8 8
 	$(d)/pl111.o \
9
-	$(d)/pi_mini_uart.o
9
+	$(d)/pi_mini_uart.o \
10
+	$(d)/bcm2835_mailbox.o \
11
+	$(d)/bcm2835_videocore.o
10 12
 
11 13
 KOBJS += $(OBJS_$(d))
12 14
 

+ 38 - 0
include/devices/bcm2835_mailbox.h

@@ -0,0 +1,38 @@
1
+/*
2
+    Copyright (C) 2012, Aaron Lindsay <aaron@aclindsay.com>
3
+
4
+    This file is part of Aedrix.
5
+
6
+    This program is free software; you can redistribute it and/or modify
7
+    it under the terms of the GNU General Public License as published by
8
+    the Free Software Foundation; either version 2 of the License, or
9
+    (at your option) any later version.
10
+
11
+    This program is distributed in the hope that it will be useful,
12
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+    GNU General Public License for more details.
15
+
16
+    You should have received a copy of the GNU General Public License along
17
+    with this program; if not, write to the Free Software Foundation, Inc.,
18
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
+ */
20
+
21
+#ifndef BCM2835_MAILBOX_H
22
+#define BCM2835_MAILBOX_H
23
+
24
+#include <types.h>
25
+
26
+/* BCM2835 Mailbox Channels */
27
+#define MBOX_PM		0	//Power management interface
28
+#define MBOX_FB		1	//Framebuffer
29
+#define MBOX_VUART	2	//Virtual UART
30
+#define MBOX_YCHIQ	3	//VCHIQ interface
31
+#define MBOX_LEDS	4	//LEDs interface
32
+#define MBOX_BUTTONS	5	//Buttons interface
33
+#define MBOX_TOUCHSCRN	6	//Touch screen interface
34
+
35
+uint32 mailbox_read(uint32 channel);
36
+void mailbox_write(uint32 channel, uint32 data);
37
+
38
+#endif /* BCM2835_MAILBOX_H */

+ 28 - 0
include/devices/bcm2835_videocore.h

@@ -0,0 +1,28 @@
1
+/*
2
+    Copyright (C) 2012, Aaron Lindsay <aaron@aclindsay.com>
3
+
4
+    This file is part of Aedrix.
5
+
6
+    This program is free software; you can redistribute it and/or modify
7
+    it under the terms of the GNU General Public License as published by
8
+    the Free Software Foundation; either version 2 of the License, or
9
+    (at your option) any later version.
10
+
11
+    This program is distributed in the hope that it will be useful,
12
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+    GNU General Public License for more details.
15
+
16
+    You should have received a copy of the GNU General Public License along
17
+    with this program; if not, write to the Free Software Foundation, Inc.,
18
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
+ */
20
+
21
+#include <framebuffer.h>
22
+
23
+#ifndef BCM2835_VIDEOCORE_H
24
+#define BCM2835_VIDEOCORE_H
25
+
26
+int bcm2835_videocore_init(struct fb *f, unsigned int color_depth);
27
+
28
+#endif /* BCM2835_VIDEOCORE_H */

+ 5 - 5
kernel/start_kernel.c

@@ -25,7 +25,7 @@
25 25
 #include <print.h>
26 26
 #include <devices/pi_mini_uart.h>
27 27
 
28
-#include <devices/pl111.h>
28
+#include <devices/bcm2835_videocore.h>
29 29
 #include <framebuffer.h>
30 30
 #include <console.h>
31 31
 
@@ -33,10 +33,10 @@ struct fb myfb;
33 33
 
34 34
 void video(void) {
35 35
 	unsigned int x, y;
36
-	pl111_init(&myfb, 24);
37
-	x = 0, y = 0;
38
-	for (y=0; y<480; y++)
39
-		for (x=0; x<640; x++)
36
+	bcm2835_videocore_init(&myfb, 16);
37
+
38
+	for (y = 0; y < myfb.height; y++)
39
+		for (x = 0; x < myfb.width; x++)
40 40
 			fb_write_pixel(&myfb, x, y, 0x3f, 0x0, 0x6f);
41 41
 
42 42
 	console_init(&myfb);