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 <masn...@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@60Hz,
 use: "setenv video-mode sunxi:1024x768-24@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@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

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to