From c64bfea23853677551e25edccf4914a999fb4d17 Mon Sep 17 00:00:00 2001 From: Aaron Lindsay Date: Sun, 7 Oct 2012 23:25:11 -0400 Subject: [PATCH] fb: Generalize framebuffer device initialization --- drivers/bcm2835_videocore.c | 17 ++++++++++++-- drivers/fb.c | 45 +++++++++++++++++++++++++++++++++++++ drivers/kernel.mk | 1 + drivers/pl111.c | 19 +++++++++++++--- include/console.h | 2 +- include/drivers/fb.h | 37 ++++++++++++++++++++++++++++++ kernel/start_kernel.c | 33 ++++++++++++++++++--------- 7 files changed, 137 insertions(+), 17 deletions(-) create mode 100644 drivers/fb.c create mode 100644 include/drivers/fb.h diff --git a/drivers/bcm2835_videocore.c b/drivers/bcm2835_videocore.c index 460cc37..c41f52d 100644 --- a/drivers/bcm2835_videocore.c +++ b/drivers/bcm2835_videocore.c @@ -18,11 +18,14 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include #include +#include #include #include +#include + #include +#include struct bcm2835_config { volatile uint32 width; @@ -43,7 +46,7 @@ struct bcm2835_config { struct fbdev bcm2835_fb_device; -int bcm2835_videocore_init(struct fb *f, unsigned int color_depth) { +int bcm2835_videocore_init_dev(struct fb *f, unsigned int color_depth) { struct bcm2835_config *cfg; uint32 result; void *mailbox_buffer_orig, *mailbox_buffer; @@ -108,3 +111,13 @@ int bcm2835_videocore_init(struct fb *f, unsigned int color_depth) { return 0; } + +struct fb_dev videocore_dev = { + .init = &bcm2835_videocore_init_dev +}; + +void bcm2835_videocore_init() { + fb_register_device(&videocore_dev); +} + +device_initcall(bcm2835_videocore_init); diff --git a/drivers/fb.c b/drivers/fb.c new file mode 100644 index 0000000..1f5d7c1 --- /dev/null +++ b/drivers/fb.c @@ -0,0 +1,45 @@ +/* + Copyright (C) 2012, Aaron Lindsay + + 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 +#include + +struct dlist_node fb_dev_list; + +int fb_register_device(struct fb_dev *fbdev) { + if (!fbdev) + return -1; + + insert_before(&fb_dev_list, &fbdev->list); + return 0; +} + +struct fb_dev *fb_first_device() { + if (list_empty(&fb_dev_list)) + return 0; + + return container(fb_dev_list.next, struct fb_dev, list); +} + +void fb_init() { + init_list(&fb_dev_list); +} + +driversubsys_initcall(fb_init); diff --git a/drivers/kernel.mk b/drivers/kernel.mk index dc5ca10..5d7547a 100644 --- a/drivers/kernel.mk +++ b/drivers/kernel.mk @@ -4,6 +4,7 @@ SUBDIRS := include $(BASEDIR)/header.mk OBJS_$(d) := \ + $(d)/fb.o \ $(d)/serial.o OBJS_$(d)_$(CONFIG_VEXPRESS_A9) := \ diff --git a/drivers/pl111.c b/drivers/pl111.c index 099dc45..e46b18e 100644 --- a/drivers/pl111.c +++ b/drivers/pl111.c @@ -18,10 +18,13 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include #include -#include +#include #include +#include +#include + +#include #define PL111_CR_EN 0x001 #define PL111_CR_PWR 0x800 @@ -40,7 +43,7 @@ struct pl111_control { struct fbdev pl111_fb_device; -int pl111_init(struct fb *f, unsigned int color_depth) { +int pl111_init_dev(struct fb *f, unsigned int color_depth) { unsigned int width, height; unsigned int fb_size, power; struct pl111_control *plio = (struct pl111_control*)PL111_IOBASE; @@ -87,3 +90,13 @@ int pl111_init(struct fb *f, unsigned int color_depth) { return 0; } + +struct fb_dev pl111_dev = { + .init = &pl111_init_dev +}; + +void pl111_init() { + fb_register_device(&pl111_dev); +} + +device_initcall(pl111_init); diff --git a/include/console.h b/include/console.h index d5bdd59..3f42474 100644 --- a/include/console.h +++ b/include/console.h @@ -21,7 +21,7 @@ #ifndef CONSOLE_H #define CONSOLE_H -void console_init(struct fb *f); +int console_init(struct fb *f); int console_putc(char c); #endif /* CONSOLE_H */ diff --git a/include/drivers/fb.h b/include/drivers/fb.h new file mode 100644 index 0000000..321795e --- /dev/null +++ b/include/drivers/fb.h @@ -0,0 +1,37 @@ +/* + Copyright (C) 2012, Aaron Lindsay + + 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 +#include + +#ifndef FB_H +#define FB_H + +struct fb_dev { + //TODO add more functions and attributes here + char *name; + int (*init)(struct fb *, unsigned int); + struct dlist_node list; +}; + +int fb_register_device(struct fb_dev *sdev); +struct fb_dev *fb_first_device(); + +#endif /* FB_H */ diff --git a/kernel/start_kernel.c b/kernel/start_kernel.c index adb7c2d..84dd077 100644 --- a/kernel/start_kernel.c +++ b/kernel/start_kernel.c @@ -28,6 +28,7 @@ #include #include +#include #ifdef CONFIG_VEXPRESS_A9 #include @@ -37,7 +38,7 @@ #include #endif -struct fb myfb; +struct fb console_fb; void print_console_logo() { print_func(&console_putc, " _ _ _\n"); @@ -48,13 +49,25 @@ void print_console_logo() { print_func(&console_putc, " Copyright (C) 2012 - Aaron Lindsay\n"); } -void video_init(void) { -#ifdef CONFIG_VEXPRESS_A9 - pl111_init(&myfb, 16); -#endif -#ifdef CONFIG_RPI - bcm2835_videocore_init(&myfb, 16); -#endif +void video_console_init(void) { + struct fb_dev *fbdev = fb_first_device(); + int ret; + + if (!fbdev) { + print("Error: No framebuffer-capable device registered."); + return; + } + + ret = fbdev->init(&console_fb, 16); + if (ret) { + print("Error: Failed to initialize framebuffer device."); + return; + } + + if ((console_init(&console_fb))) + return; + + print_console_logo(); } void serial_console_init() { @@ -100,9 +113,7 @@ int main(void) { init_initcalls(); - video_init(); - console_init(&myfb); - print_console_logo(); + video_console_init(); return 0; }