Add BCM2835 (Raspberry Pi) framebuffer and mailbox implementations
This commit is contained in:
		
							
								
								
									
										69
									
								
								devices/bcm2835_mailbox.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								devices/bcm2835_mailbox.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,69 @@ | |||||||
|  | /* | ||||||
|  |     Copyright (C) 2012, Aaron Lindsay <aaron@aclindsay.com> | ||||||
|  |  | ||||||
|  |     This file is part of Aedrix. | ||||||
|  |  | ||||||
|  |     This program is free software; you can redistribute it and/or modify | ||||||
|  |     it under the terms of the GNU General Public License as published by | ||||||
|  |     the Free Software Foundation; either version 2 of the License, or | ||||||
|  |     (at your option) any later version. | ||||||
|  |  | ||||||
|  |     This program is distributed in the hope that it will be useful, | ||||||
|  |     but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |     GNU General Public License for more details. | ||||||
|  |  | ||||||
|  |     You should have received a copy of the GNU General Public License along | ||||||
|  |     with this program; if not, write to the Free Software Foundation, Inc., | ||||||
|  |     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include <types.h> | ||||||
|  |  | ||||||
|  | /* Mailbox Memory-Mapped Registers */ | ||||||
|  | #define VC_MMU_IO_OFFSET(addr) (addr - 0x7E000000 + 0x20000000) | ||||||
|  |  | ||||||
|  | #define MBOX0_READ	VC_MMU_IO_OFFSET(0x7E00B880) | ||||||
|  | /*	MBOX0_READ layout: | ||||||
|  | 	31-4	data	The 28 bits of data sent to the CPU | ||||||
|  | 	3-0	channel	The mailbox channel number from which the data originated */ | ||||||
|  | #define MBOX0_PEEK	VC_MMU_IO_OFFSET(0x7E00B890)	//Read from the mailbox without removing data from it. | ||||||
|  | #define MBOX0_SENDER	VC_MMU_IO_OFFSET(0x7E00B894)	//Sender ID (bottom 2 bits only) | ||||||
|  | #define MBOX0_STATUS	VC_MMU_IO_OFFSET(0x7E00B898) | ||||||
|  | /*	MBOX0_STATUS layout: | ||||||
|  | 	31	full	Set if the mailbox is full, and thus no more data can be written to it. | ||||||
|  | 	30	empty	Set if the mailbox is empty, and thus no more data is available to be read from it. | ||||||
|  | 	29-0		unused? */ | ||||||
|  | #define MBOX0_CONFIG	VC_MMU_IO_OFFSET(0x7E00B89C) | ||||||
|  | #define MBOX0_WRITE	VC_MMU_IO_OFFSET(0x7E00B8A0)	//also MBOX1_READ? | ||||||
|  | /*	MBOX0_WRITE layout: | ||||||
|  | 	31-4	data	The 28 bits of data to be sent | ||||||
|  | 	3-0	channel	The mailbox channel to send data to */ | ||||||
|  |  | ||||||
|  | #define MBOX0_STATUS_FULL	0x80000000 | ||||||
|  | #define MBOX0_STATUS_EMPTY	0x40000000 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | uint32 mailbox_read(uint32 channel) { | ||||||
|  | 	uint32 mbox_msg; | ||||||
|  | 	while (1) { | ||||||
|  | 		int i; | ||||||
|  | 		for (i = 0; *(volatile uint32 *)MBOX0_STATUS & MBOX0_STATUS_EMPTY; i++) { | ||||||
|  | 			if (i >= 1<<20) | ||||||
|  | 				return 0xFFFFFFFF; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		mbox_msg = *(volatile uint32 *)MBOX0_READ; | ||||||
|  | 		if ((mbox_msg & 0xf) == channel) | ||||||
|  | 			return mbox_msg & ~0xf; | ||||||
|  | 	} | ||||||
|  | }  | ||||||
|  |  | ||||||
|  | void mailbox_write(uint32 channel, uint32 data) { | ||||||
|  | 	channel &= 0xf; | ||||||
|  | 	data &= ~0xf; | ||||||
|  |  | ||||||
|  | 	while (*(volatile uint32 *)MBOX0_STATUS & MBOX0_STATUS_FULL); | ||||||
|  |  | ||||||
|  | 	*(volatile uint32 *)MBOX0_WRITE = channel | data; | ||||||
|  | } | ||||||
							
								
								
									
										94
									
								
								devices/bcm2835_videocore.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								devices/bcm2835_videocore.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,94 @@ | |||||||
|  | /* | ||||||
|  |     Copyright (C) 2012, Aaron Lindsay <aaron@aclindsay.com> | ||||||
|  |  | ||||||
|  |     This file is part of Aedrix. | ||||||
|  |  | ||||||
|  |     This program is free software; you can redistribute it and/or modify | ||||||
|  |     it under the terms of the GNU General Public License as published by | ||||||
|  |     the Free Software Foundation; either version 2 of the License, or | ||||||
|  |     (at your option) any later version. | ||||||
|  |  | ||||||
|  |     This program is distributed in the hope that it will be useful, | ||||||
|  |     but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |     GNU General Public License for more details. | ||||||
|  |  | ||||||
|  |     You should have received a copy of the GNU General Public License along | ||||||
|  |     with this program; if not, write to the Free Software Foundation, Inc., | ||||||
|  |     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include <types.h> | ||||||
|  | #include <framebuffer.h> | ||||||
|  | #include <kmalloc.h> | ||||||
|  | #include <print.h> | ||||||
|  | #include <devices/bcm2835_mailbox.h> | ||||||
|  |  | ||||||
|  | struct bcm2835_config { | ||||||
|  | 	uint32 width; | ||||||
|  | 	uint32 height; | ||||||
|  | 	uint32 vwidth; | ||||||
|  | 	uint32 vheight; | ||||||
|  | 	uint32 pitch; | ||||||
|  | 	uint32 color_depth; | ||||||
|  | 	uint32 xoffset; | ||||||
|  | 	uint32 yoffset; | ||||||
|  | 	uint32 fb_base_addr; | ||||||
|  | 	uint32 size; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #define MAILBOX_BUFFER_SIZE (32*4*2) | ||||||
|  | #define FB_WIDTH 1024 | ||||||
|  | #define FB_HEIGHT 768 | ||||||
|  |  | ||||||
|  | struct fbdev bcm2835_fb_device; | ||||||
|  |  | ||||||
|  | int bcm2835_videocore_init(struct fb *f, unsigned int color_depth) { | ||||||
|  | 	struct bcm2835_config *cfg; | ||||||
|  | 	uint32 result; | ||||||
|  | 	void *mailbox_buffer_orig, *mailbox_buffer; | ||||||
|  |  | ||||||
|  | 	if (!(mailbox_buffer_orig = kmalloc(MAILBOX_BUFFER_SIZE))) { | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/* Round mailbox buffer to multiple of 0x10 because the low 4 bits of | ||||||
|  | 	the mailbox are used to send the channel, and therefore can't hold the low 4 | ||||||
|  | 	bits of the address */ | ||||||
|  | 	if ((uint32)mailbox_buffer_orig & 0xf) | ||||||
|  | 		mailbox_buffer = (void *)((uint32)mailbox_buffer_orig & ~0xf) + 0x10; | ||||||
|  | 	else | ||||||
|  | 		mailbox_buffer = mailbox_buffer_orig; | ||||||
|  |  | ||||||
|  | 	cfg = (struct bcm2835_config *)mailbox_buffer; | ||||||
|  | 	cfg->width = FB_WIDTH; | ||||||
|  | 	cfg->height = FB_HEIGHT; | ||||||
|  | 	cfg->vwidth = FB_WIDTH; | ||||||
|  | 	cfg->vheight = FB_HEIGHT; | ||||||
|  | 	cfg->pitch = 0; | ||||||
|  | 	cfg->color_depth = color_depth; | ||||||
|  | 	cfg->xoffset = 0; | ||||||
|  | 	cfg->yoffset = 0; | ||||||
|  | 	cfg->fb_base_addr = 0; | ||||||
|  | 	cfg->size = 0; | ||||||
|  |  | ||||||
|  | 	mailbox_write(MBOX_FB, (uint32)cfg); | ||||||
|  | 	result = mailbox_read(MBOX_FB); | ||||||
|  |  | ||||||
|  | 	if (result || !cfg->fb_base_addr) { | ||||||
|  | 		print("Error: did not request a proper framebuffer\n"); | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	f->device = &bcm2835_fb_device; | ||||||
|  | 	f->device->fbaddr = (void*)cfg->fb_base_addr; | ||||||
|  | 	f->width = cfg->width; | ||||||
|  | 	f->device->pixelwidth = cfg->width; | ||||||
|  | 	f->height = cfg->height; | ||||||
|  | 	f->device->pixelheight = cfg->height; | ||||||
|  |  | ||||||
|  | 	f->color_depth = color_depth; | ||||||
|  | 	f->device->color_depth = color_depth; | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
| @@ -6,7 +6,9 @@ include $(BASEDIR)/header.mk | |||||||
| OBJS_$(d) := $(d)/pl011.o \ | OBJS_$(d) := $(d)/pl011.o \ | ||||||
| 	$(d)/pl110.o \ | 	$(d)/pl110.o \ | ||||||
| 	$(d)/pl111.o \ | 	$(d)/pl111.o \ | ||||||
| 	$(d)/pi_mini_uart.o | 	$(d)/pi_mini_uart.o \ | ||||||
|  | 	$(d)/bcm2835_mailbox.o \ | ||||||
|  | 	$(d)/bcm2835_videocore.o | ||||||
|  |  | ||||||
| KOBJS += $(OBJS_$(d)) | KOBJS += $(OBJS_$(d)) | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										38
									
								
								include/devices/bcm2835_mailbox.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								include/devices/bcm2835_mailbox.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | |||||||
|  | /* | ||||||
|  |     Copyright (C) 2012, Aaron Lindsay <aaron@aclindsay.com> | ||||||
|  |  | ||||||
|  |     This file is part of Aedrix. | ||||||
|  |  | ||||||
|  |     This program is free software; you can redistribute it and/or modify | ||||||
|  |     it under the terms of the GNU General Public License as published by | ||||||
|  |     the Free Software Foundation; either version 2 of the License, or | ||||||
|  |     (at your option) any later version. | ||||||
|  |  | ||||||
|  |     This program is distributed in the hope that it will be useful, | ||||||
|  |     but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |     GNU General Public License for more details. | ||||||
|  |  | ||||||
|  |     You should have received a copy of the GNU General Public License along | ||||||
|  |     with this program; if not, write to the Free Software Foundation, Inc., | ||||||
|  |     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #ifndef BCM2835_MAILBOX_H | ||||||
|  | #define BCM2835_MAILBOX_H | ||||||
|  |  | ||||||
|  | #include <types.h> | ||||||
|  |  | ||||||
|  | /* BCM2835 Mailbox Channels */ | ||||||
|  | #define MBOX_PM		0	//Power management interface | ||||||
|  | #define MBOX_FB		1	//Framebuffer | ||||||
|  | #define MBOX_VUART	2	//Virtual UART | ||||||
|  | #define MBOX_YCHIQ	3	//VCHIQ interface | ||||||
|  | #define MBOX_LEDS	4	//LEDs interface | ||||||
|  | #define MBOX_BUTTONS	5	//Buttons interface | ||||||
|  | #define MBOX_TOUCHSCRN	6	//Touch screen interface | ||||||
|  |  | ||||||
|  | uint32 mailbox_read(uint32 channel); | ||||||
|  | void mailbox_write(uint32 channel, uint32 data); | ||||||
|  |  | ||||||
|  | #endif /* BCM2835_MAILBOX_H */ | ||||||
							
								
								
									
										28
									
								
								include/devices/bcm2835_videocore.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								include/devices/bcm2835_videocore.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | |||||||
|  | /* | ||||||
|  |     Copyright (C) 2012, Aaron Lindsay <aaron@aclindsay.com> | ||||||
|  |  | ||||||
|  |     This file is part of Aedrix. | ||||||
|  |  | ||||||
|  |     This program is free software; you can redistribute it and/or modify | ||||||
|  |     it under the terms of the GNU General Public License as published by | ||||||
|  |     the Free Software Foundation; either version 2 of the License, or | ||||||
|  |     (at your option) any later version. | ||||||
|  |  | ||||||
|  |     This program is distributed in the hope that it will be useful, | ||||||
|  |     but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |     GNU General Public License for more details. | ||||||
|  |  | ||||||
|  |     You should have received a copy of the GNU General Public License along | ||||||
|  |     with this program; if not, write to the Free Software Foundation, Inc., | ||||||
|  |     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include <framebuffer.h> | ||||||
|  |  | ||||||
|  | #ifndef BCM2835_VIDEOCORE_H | ||||||
|  | #define BCM2835_VIDEOCORE_H | ||||||
|  |  | ||||||
|  | int bcm2835_videocore_init(struct fb *f, unsigned int color_depth); | ||||||
|  |  | ||||||
|  | #endif /* BCM2835_VIDEOCORE_H */ | ||||||
| @@ -25,7 +25,7 @@ | |||||||
| #include <print.h> | #include <print.h> | ||||||
| #include <devices/pi_mini_uart.h> | #include <devices/pi_mini_uart.h> | ||||||
|  |  | ||||||
| #include <devices/pl111.h> | #include <devices/bcm2835_videocore.h> | ||||||
| #include <framebuffer.h> | #include <framebuffer.h> | ||||||
| #include <console.h> | #include <console.h> | ||||||
|  |  | ||||||
| @@ -33,10 +33,10 @@ struct fb myfb; | |||||||
|  |  | ||||||
| void video(void) { | void video(void) { | ||||||
| 	unsigned int x, y; | 	unsigned int x, y; | ||||||
| 	pl111_init(&myfb, 24); | 	bcm2835_videocore_init(&myfb, 16); | ||||||
| 	x = 0, y = 0; |  | ||||||
| 	for (y=0; y<480; y++) | 	for (y = 0; y < myfb.height; y++) | ||||||
| 		for (x=0; x<640; x++) | 		for (x = 0; x < myfb.width; x++) | ||||||
| 			fb_write_pixel(&myfb, x, y, 0x3f, 0x0, 0x6f); | 			fb_write_pixel(&myfb, x, y, 0x3f, 0x0, 0x6f); | ||||||
|  |  | ||||||
| 	console_init(&myfb); | 	console_init(&myfb); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user