]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
video: add a driver for the bcm2835
authorStephen Warren <swarren@wwwdotorg.org>
Tue, 29 Jan 2013 16:37:40 +0000 (16:37 +0000)
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>
Wed, 20 Mar 2013 14:30:00 +0000 (15:30 +0100)
The firmware running on the bcm2835 SoC's VideoCore CPU manages the
display controller. Add a simple "LCD" driver that communicates with the
firmware using the property mailbox protocol. This configures the
display and frame-buffer to match whatever physical resolution the
firmware chosen when booting, which is typically the native resolution
of the attached display device, presumably unless otherwise specified
in config.txt on the boot media.

Enable this driver in the Raspberry Pi board configuration.

Signed-off-by: Stephen Warren <swarren@wwwdotorg.org>
Acked-by: Anatolij Gustschin <agust@denx.de>
drivers/video/Makefile
drivers/video/bcm2835.c [new file with mode: 0644]
include/configs/rpi_b.h

index 170a358b5283849207827f21d7eb49dc419d9acf..e8cecca55a93db2a663e31483a69603e4b0ccab9 100644 (file)
@@ -40,6 +40,7 @@ COBJS-$(CONFIG_S6E63D6) += s6e63d6.o
 COBJS-$(CONFIG_LD9040) += ld9040.o
 COBJS-$(CONFIG_SED156X) += sed156x.o
 COBJS-$(CONFIG_VIDEO_AMBA) += amba.o
+COBJS-$(CONFIG_VIDEO_BCM2835) += bcm2835.o
 COBJS-$(CONFIG_VIDEO_COREBOOT) += coreboot_fb.o
 COBJS-$(CONFIG_VIDEO_CT69000) += ct69000.o videomodes.o
 COBJS-$(CONFIG_VIDEO_DA8XX) += da8xx-fb.o videomodes.o
diff --git a/drivers/video/bcm2835.c b/drivers/video/bcm2835.c
new file mode 100644 (file)
index 0000000..1e9a84a
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * (C) Copyright 2012 Stephen Warren
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <lcd.h>
+#include <asm/arch/mbox.h>
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Global variables that lcd.c expects to exist */
+int lcd_line_length;
+int lcd_color_fg;
+int lcd_color_bg;
+void *lcd_base;
+void *lcd_console_address;
+short console_col;
+short console_row;
+vidinfo_t panel_info;
+char lcd_cursor_enabled;
+ushort lcd_cursor_width;
+ushort lcd_cursor_height;
+
+struct msg_query {
+       struct bcm2835_mbox_hdr hdr;
+       struct bcm2835_mbox_tag_physical_w_h physical_w_h;
+       u32 end_tag;
+};
+
+struct msg_setup {
+       struct bcm2835_mbox_hdr hdr;
+       struct bcm2835_mbox_tag_physical_w_h physical_w_h;
+       struct bcm2835_mbox_tag_virtual_w_h virtual_w_h;
+       struct bcm2835_mbox_tag_depth depth;
+       struct bcm2835_mbox_tag_pixel_order pixel_order;
+       struct bcm2835_mbox_tag_alpha_mode alpha_mode;
+       struct bcm2835_mbox_tag_virtual_offset virtual_offset;
+       struct bcm2835_mbox_tag_overscan overscan;
+       struct bcm2835_mbox_tag_allocate_buffer allocate_buffer;
+       u32 end_tag;
+};
+
+void lcd_ctrl_init(void *lcdbase)
+{
+       ALLOC_ALIGN_BUFFER(struct msg_query, msg_query, 1, 16);
+       ALLOC_ALIGN_BUFFER(struct msg_setup, msg_setup, 1, 16);
+       int ret;
+       u32 w, h;
+
+       debug("bcm2835: Query resolution...\n");
+
+       BCM2835_MBOX_INIT_HDR(msg_query);
+       BCM2835_MBOX_INIT_TAG_NO_REQ(&msg_query->physical_w_h,
+                                       GET_PHYSICAL_W_H);
+       ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg_query->hdr);
+       if (ret) {
+               printf("bcm2835: Could not query display resolution\n");
+               /* FIXME: How to disable the LCD to prevent errors? hang()? */
+               return;
+       }
+
+       w = msg_query->physical_w_h.body.resp.width;
+       h = msg_query->physical_w_h.body.resp.height;
+
+       debug("bcm2835: Setting up display for %d x %d\n", w, h);
+
+       BCM2835_MBOX_INIT_HDR(msg_setup);
+       BCM2835_MBOX_INIT_TAG(&msg_setup->physical_w_h, SET_PHYSICAL_W_H);
+       msg_setup->physical_w_h.body.req.width = w;
+       msg_setup->physical_w_h.body.req.height = h;
+       BCM2835_MBOX_INIT_TAG(&msg_setup->virtual_w_h, SET_VIRTUAL_W_H);
+       msg_setup->virtual_w_h.body.req.width = w;
+       msg_setup->virtual_w_h.body.req.height = h;
+       BCM2835_MBOX_INIT_TAG(&msg_setup->depth, SET_DEPTH);
+       msg_setup->depth.body.req.bpp = 16;
+       BCM2835_MBOX_INIT_TAG(&msg_setup->pixel_order, SET_PIXEL_ORDER);
+       msg_setup->pixel_order.body.req.order = BCM2835_MBOX_PIXEL_ORDER_BGR;
+       BCM2835_MBOX_INIT_TAG(&msg_setup->alpha_mode, SET_ALPHA_MODE);
+       msg_setup->alpha_mode.body.req.alpha = BCM2835_MBOX_ALPHA_MODE_IGNORED;
+       BCM2835_MBOX_INIT_TAG(&msg_setup->virtual_offset, SET_VIRTUAL_OFFSET);
+       msg_setup->virtual_offset.body.req.x = 0;
+       msg_setup->virtual_offset.body.req.y = 0;
+       BCM2835_MBOX_INIT_TAG(&msg_setup->overscan, SET_OVERSCAN);
+       msg_setup->overscan.body.req.top = 0;
+       msg_setup->overscan.body.req.bottom = 0;
+       msg_setup->overscan.body.req.left = 0;
+       msg_setup->overscan.body.req.right = 0;
+       BCM2835_MBOX_INIT_TAG(&msg_setup->allocate_buffer, ALLOCATE_BUFFER);
+       msg_setup->allocate_buffer.body.req.alignment = 0x100;
+
+       ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg_setup->hdr);
+       if (ret) {
+               printf("bcm2835: Could not configure display\n");
+               /* FIXME: How to disable the LCD to prevent errors? hang()? */
+               return;
+       }
+
+       w = msg_setup->physical_w_h.body.resp.width;
+       h = msg_setup->physical_w_h.body.resp.height;
+
+       debug("bcm2835: Final resolution is %d x %d\n", w, h);
+
+       panel_info.vl_col = w;
+       panel_info.vl_row = h;
+       panel_info.vl_bpix = LCD_COLOR16;
+
+       gd->fb_base = msg_setup->allocate_buffer.body.resp.fb_address;
+       lcd_base = (void *)gd->fb_base;
+}
+
+void lcd_enable(void)
+{
+}
index 5db31f58be982d41eca2a272f949d33389aa8793..e485a061a61ea4a76daa1b892ba2ba751c1f714d 100644 (file)
 /* Devices */
 /* GPIO */
 #define CONFIG_BCM2835_GPIO
+/* LCD */
+#define CONFIG_LCD
+#define LCD_BPP                                LCD_COLOR16
+/*
+ * Prevent allocation of RAM for FB; the real FB address is queried
+ * dynamically from the VideoCore co-processor, and comes from RAM
+ * not owned by the ARM CPU.
+ */
+#define CONFIG_FB_ADDR                 0
+#define CONFIG_VIDEO_BCM2835
+#define CONFIG_SYS_WHITE_ON_BLACK
 
 /* Console UART */
 #define CONFIG_PL011_SERIAL
 #define CONFIG_ENV_SIZE                        SZ_16K
 #define CONFIG_ENV_IS_NOWHERE
 #define CONFIG_SYS_LOAD_ADDR           0x1000000
+#define CONFIG_CONSOLE_MUX
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV
+#define CONFIG_EXTRA_ENV_SETTINGS      "stdin=serial\0" \
+                                       "stderr=serial,lcd\0" \
+                                       "stdout=serial,lcd\0"
 
 /* Shell */
 #define CONFIG_SYS_HUSH_PARSER