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 \ | ||||
| 	$(d)/pl110.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)) | ||||
|  | ||||
|   | ||||
							
								
								
									
										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 <devices/pi_mini_uart.h> | ||||
|  | ||||
| #include <devices/pl111.h> | ||||
| #include <devices/bcm2835_videocore.h> | ||||
| #include <framebuffer.h> | ||||
| #include <console.h> | ||||
|  | ||||
| @@ -33,10 +33,10 @@ struct fb myfb; | ||||
|  | ||||
| void video(void) { | ||||
| 	unsigned int x, y; | ||||
| 	pl111_init(&myfb, 24); | ||||
| 	x = 0, y = 0; | ||||
| 	for (y=0; y<480; y++) | ||||
| 		for (x=0; x<640; x++) | ||||
| 	bcm2835_videocore_init(&myfb, 16); | ||||
|  | ||||
| 	for (y = 0; y < myfb.height; y++) | ||||
| 		for (x = 0; x < myfb.width; x++) | ||||
| 			fb_write_pixel(&myfb, x, y, 0x3f, 0x0, 0x6f); | ||||
|  | ||||
| 	console_init(&myfb); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user