[U-Boot] [PATCH] video: bcm2835: add support for reading from the video-mode environment variable

Brian Masney masneyb at onstation.org
Tue Nov 15 12:07:41 CET 2016


The bcm2835 driver polls the monitor and selects the highest resolution
that is available. This patch allows optionally setting the video-mode
environment variable so that a different video resolution can be used.
If the environment variable is not specified, then it will fall back to
using the old behavior of using the maximum allowable resolution.

This patch is needed to fix an issue booting an upstream Linux kernel
on a Raspberry Pi 2 with a Pi Top screen. Previously, the bcm2835 would
select the 1366x768 resolution (which is a supported resolution), however
the screen would be unreadable. (See
https://www.flickr.com/photos/masneyb/30942037416/ for picture). Using
this patch, the resolution 1024x768 can be selected and is readable on
the screen.

Signed-off-by: Brian Masney <masneyb at onstation.org>
---
 doc/README.video        | 12 ++++++++++++
 drivers/video/Makefile  |  2 +-
 drivers/video/bcm2835.c | 42 +++++++++++++++++++++++++++++-------------
 3 files changed, 42 insertions(+), 14 deletions(-)

diff --git a/doc/README.video b/doc/README.video
index e7ae98a..31ceeab 100644
--- a/doc/README.video
+++ b/doc/README.video
@@ -76,3 +76,15 @@ The sunxi U-Boot driver supports the following video-mode options:
 For example to always use the hdmi connector, even if no cable is inserted,
 using edid info when available and otherwise initalizing it at 1024x768 at 60Hz,
 use: "setenv video-mode sunxi:1024x768-24 at 60,monitor=dvi,hpd=0,edid=1".
+
+
+U-Boot bcm2835 video controller driver
+======================================
+
+The bcm2835 driver supports polling the monitor for the maximum supported
+resolution. This can be changed by using the video-mode environment
+variable:
+
+Example: video-mode=bcm2835:1024x768-16 at 60
+
+Note: The frequency is currently not used by the driver.
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 3f045fe..76dfd69 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -35,7 +35,7 @@ obj-$(CONFIG_S6E8AX0) += s6e8ax0.o
 obj-$(CONFIG_S6E63D6) += s6e63d6.o
 obj-$(CONFIG_LD9040) += ld9040.o
 obj-$(CONFIG_SED156X) += sed156x.o
-obj-$(CONFIG_VIDEO_BCM2835) += bcm2835.o
+obj-$(CONFIG_VIDEO_BCM2835) += bcm2835.o videomodes.o
 obj-$(CONFIG_VIDEO_COREBOOT) += coreboot_fb.o
 obj-$(CONFIG_VIDEO_CT69000) += ct69000.o videomodes.o
 obj-$(CONFIG_VIDEO_DA8XX) += da8xx-fb.o videomodes.o
diff --git a/drivers/video/bcm2835.c b/drivers/video/bcm2835.c
index cd605e6..657f854 100644
--- a/drivers/video/bcm2835.c
+++ b/drivers/video/bcm2835.c
@@ -10,6 +10,7 @@
 #include <phys2bus.h>
 #include <asm/arch/mbox.h>
 #include <asm/global_data.h>
+#include "videomodes.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -45,21 +46,36 @@ void lcd_ctrl_init(void *lcdbase)
 	int ret;
 	u32 w, h;
 	u32 fb_start, fb_end;
+	const char *options;
+	unsigned int depth = 0, freq = 0;
 
-	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;
+	if (video_get_video_mode(&w, &h, &depth, &freq, &options) != 1) {
+		debug("bcm2835: video_get_video_mode() unsuccessful; polling monitor for defaults\n");
+		w = 0;
+		h = 0;
 	}
 
-	w = msg_query->physical_w_h.body.resp.width;
-	h = msg_query->physical_w_h.body.resp.height;
+	if (w == 0 || h == 0) {
+		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;
+
+		depth = 16;
+	}
 
 	debug("bcm2835: Setting up display for %d x %d\n", w, h);
 
@@ -71,7 +87,7 @@ void lcd_ctrl_init(void *lcdbase)
 	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;
+	msg_setup->depth.body.req.bpp = depth;
 	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);
-- 
2.7.4



More information about the U-Boot mailing list