Add BCM2835 (Raspberry Pi) framebuffer and mailbox implementations
This commit is contained in:
parent
925192fca1
commit
af22b6fe46
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);
|
||||||
|
Loading…
Reference in New Issue
Block a user