]> git.sur5r.net Git - u-boot/commitdiff
sandbox: Add LCD driver
authorSimon Glass <sjg@chromium.org>
Thu, 27 Feb 2014 20:26:19 +0000 (13:26 -0700)
committerSimon Glass <sjg@chromium.org>
Tue, 18 Mar 2014 02:05:49 +0000 (20:05 -0600)
Add a simple LCD driver which uses SDL to display the image. We update the
image regularly, while still providing for reasonable performance.

Adjust the common lcd code to support sandbox.

For command-line runs we do not want the LCD to be displayed, so add a
--show_lcd option to enable it.

Tested-by: Che-Liang Chiou <clchiou@chromium.org>
Signed-off-by: Simon Glass <sjg@chromium.org>
12 files changed:
arch/sandbox/cpu/start.c
arch/sandbox/include/asm/state.h
arch/sandbox/include/asm/u-boot-sandbox.h
board/sandbox/sandbox/sandbox.c
common/lcd.c
doc/device-tree-bindings/video/sandbox-fb.txt [new file with mode: 0644]
drivers/serial/sandbox.c
drivers/video/Makefile
drivers/video/sandbox_sdl.c [new file with mode: 0644]
include/fdtdec.h
include/lcd.h
lib/fdtdec.c

index 2d19fe795e06baef0e6229ea3675fe8b6a6b714d..4d5569e6476725d1f2a099a07369e40bd5237914 100644 (file)
@@ -175,6 +175,15 @@ static int sandbox_cmdline_cb_ignore_missing(struct sandbox_state *state,
 SANDBOX_CMDLINE_OPT_SHORT(ignore_missing, 'n', 0,
                          "Ignore missing state on read");
 
+static int sandbox_cmdline_cb_show_lcd(struct sandbox_state *state,
+                                      const char *arg)
+{
+       state->show_lcd = true;
+       return 0;
+}
+SANDBOX_CMDLINE_OPT_SHORT(show_lcd, 'l', 0,
+                         "Show the sandbox LCD display");
+
 int main(int argc, char *argv[])
 {
        struct sandbox_state *state;
index 304104e058e36b0455e3c0701dbb1843a26e69db..895b3a4ec7b3b5f2add23d03f25dbf0511dcab79 100644 (file)
@@ -41,6 +41,7 @@ struct sandbox_state {
        bool read_state;                /* Read sandbox state on startup */
        bool write_state;               /* Write sandbox state on exit */
        bool ignore_missing_state_on_read;      /* No error if state missing */
+       bool show_lcd;                  /* Show LCD on start-up */
 
        /* Pointer to information for each SPI bus/cs */
        struct sandbox_spi_info spi[CONFIG_SANDBOX_SPI_MAX_BUS]
index 5707c2710d9fc1707ae25df940c82fe81260950f..d2f1b6566d7051afe75c1199a57c929fabcd0ae3 100644 (file)
@@ -25,4 +25,7 @@ int sandbox_main_loop_init(void);
 
 int cleanup_before_linux(void);
 
+/* drivers/video/sandbox_sdl.c */
+int sandbox_lcd_sdl_early_init(void);
+
 #endif /* _U_BOOT_SANDBOX_H_ */
index 402afea8110ac1a6bb39c7a96734dd2a89b1dde8..e4d4e021bcd9ff0fb26cc6121a4c103ace7f1c5b 100644 (file)
@@ -7,6 +7,7 @@
 #include <cros_ec.h>
 #include <dm.h>
 #include <os.h>
+#include <asm/u-boot-sandbox.h>
 
 /*
  * Pointer to initial global data area
@@ -35,6 +36,23 @@ int dram_init(void)
        return 0;
 }
 
+#ifdef CONFIG_BOARD_EARLY_INIT_F
+int board_early_init_f(void)
+{
+#ifdef CONFIG_VIDEO_SANDBOX_SDL
+       int ret;
+
+       ret = sandbox_lcd_sdl_early_init();
+       if (ret) {
+               puts("Could not init sandbox LCD emulation\n");
+               return ret;
+       }
+#endif
+
+       return 0;
+}
+#endif
+
 int arch_early_init_r(void)
 {
 #ifdef CONFIG_CROS_EC
index aa81522fffef5e763dfbcb1f89b46d55ac0e1911..19b86b7c55013abc621621aaf94f06fe095d63dc 100644 (file)
@@ -28,6 +28,8 @@
 #include <watchdog.h>
 #include <asm/unaligned.h>
 #include <splash.h>
+#include <asm/io.h>
+#include <asm/unaligned.h>
 
 #if defined(CONFIG_CPU_PXA25X) || defined(CONFIG_CPU_PXA27X) || \
        defined(CONFIG_CPU_MONAHANS)
 # endif
 #endif
 
+#ifdef CONFIG_SANDBOX
+#include <asm/sdl.h>
+#endif
+
 #ifndef CONFIG_LCD_ALIGNMENT
 #define CONFIG_LCD_ALIGNMENT PAGE_SIZE
 #endif
@@ -144,6 +150,13 @@ void lcd_sync(void)
        if (lcd_flush_dcache)
                flush_dcache_range((u32)lcd_base,
                        (u32)(lcd_base + lcd_get_size(&line_length)));
+#elif defined(CONFIG_SANDBOX) && defined(CONFIG_VIDEO_SANDBOX_SDL)
+       static ulong last_sync;
+
+       if (get_timer(last_sync) > 10) {
+               sandbox_sdl_sync(lcd_base);
+               last_sync = get_timer(0);
+       }
 #endif
 }
 
@@ -403,7 +416,7 @@ int drv_lcd_init(void)
        struct stdio_dev lcddev;
        int rc;
 
-       lcd_base = (void *) gd->fb_base;
+       lcd_base = map_sysmem(gd->fb_base, 0);
 
        lcd_init(lcd_base);             /* LCD initialization */
 
@@ -494,8 +507,8 @@ static int lcd_init(void *lcdbase)
         * by setting up gd->fb_base. Check for this condition and fixup
         * 'lcd_base' address.
         */
-       if ((unsigned long)lcdbase != gd->fb_base)
-               lcd_base = (void *)gd->fb_base;
+       if (map_to_sysmem(lcdbase) != gd->fb_base)
+               lcd_base = map_sysmem(gd->fb_base, 0);
 
        debug("[LCD] Using LCD frambuffer at %p\n", lcd_base);
 
@@ -886,7 +899,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
        ushort *cmap_base = NULL;
        ushort i, j;
        uchar *fb;
-       bmp_image_t *bmp=(bmp_image_t *)bmp_image;
+       bmp_image_t *bmp = (bmp_image_t *)map_sysmem(bmp_image, 0);
        uchar *bmap;
        ushort padded_width;
        unsigned long width, height, byte_width;
diff --git a/doc/device-tree-bindings/video/sandbox-fb.txt b/doc/device-tree-bindings/video/sandbox-fb.txt
new file mode 100644 (file)
index 0000000..eb91b30
--- /dev/null
@@ -0,0 +1,13 @@
+Sandbox LCD
+===========
+
+This uses the displaymode.txt binding except that only xres and yres are
+required properties.
+
+Example:
+
+       lcd {
+               compatible = "sandbox,lcd-sdl";
+               xres = <800>;
+               yres = <600>;
+       };
index ffff5e149774bb6950ec6f9097ea1c6730fa5261..c27b5b8fe52b4420e2b5b6160d193a758eff8653 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <common.h>
+#include <lcd.h>
 #include <os.h>
 #include <serial.h>
 #include <linux/compiler.h>
@@ -60,6 +61,9 @@ static int sandbox_serial_tstc(void)
        ssize_t count;
 
        os_usleep(100);
+#ifdef CONFIG_LCD
+       lcd_sync();
+#endif
        if (next_index == serial_buf_read)
                return 1;       /* buffer full */
 
index a7f54698acf638b92dc4e6b62f0ee2ed73e3bc21..c527029241ac2714bd93f7b9b11d82f94d1bf72c 100644 (file)
@@ -33,6 +33,7 @@ obj-$(CONFIG_VIDEO_MX3) += mx3fb.o videomodes.o
 obj-$(CONFIG_VIDEO_IPUV3) += mxc_ipuv3_fb.o ipu_common.o ipu_disp.o
 obj-$(CONFIG_VIDEO_MXS) += mxsfb.o videomodes.o
 obj-$(CONFIG_VIDEO_OMAP3) += omap3_dss.o
+obj-$(CONFIG_VIDEO_SANDBOX_SDL) += sandbox_sdl.o
 obj-$(CONFIG_VIDEO_SED13806) += sed13806.o
 obj-$(CONFIG_VIDEO_SM501) += sm501.o
 obj-$(CONFIG_VIDEO_SMI_LYNXEM) += smiLynxEM.o videomodes.o
diff --git a/drivers/video/sandbox_sdl.c b/drivers/video/sandbox_sdl.c
new file mode 100644 (file)
index 0000000..ba4578e
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2013 Google, Inc
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <lcd.h>
+#include <malloc.h>
+#include <asm/sdl.h>
+#include <asm/u-boot-sandbox.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum {
+       /* Maximum LCD size we support */
+       LCD_MAX_WIDTH           = 1366,
+       LCD_MAX_HEIGHT          = 768,
+       LCD_MAX_LOG2_BPP        = 4,            /* 2^4 = 16 bpp */
+};
+
+vidinfo_t panel_info;
+
+void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue)
+{
+}
+
+void lcd_ctrl_init(void *lcdbase)
+{
+       /*
+        * Allocate memory to keep BMP color conversion map. This is required
+        * for 8 bit BMPs only (hence 256 colors). If malloc fails - keep
+        * going, it is not even clear if displyaing the bitmap will be
+        * required on the way up.
+        */
+       panel_info.cmap = malloc(256 * NBITS(panel_info.vl_bpix) / 8);
+}
+
+void lcd_enable(void)
+{
+       if (sandbox_sdl_init_display(panel_info.vl_col, panel_info.vl_row,
+                                    panel_info.vl_bpix))
+               puts("LCD init failed\n");
+}
+
+int sandbox_lcd_sdl_early_init(void)
+{
+       const void *blob = gd->fdt_blob;
+       int xres = LCD_MAX_WIDTH, yres = LCD_MAX_HEIGHT;
+       int node;
+       int ret = 0;
+
+       /*
+        * The code in common/lcd.c does not cope with not being able to
+        * set up a frame buffer. It will just happily keep writing to
+        * invalid memory. So here we make sure that at least some buffer
+        * is available even if it actually won't be displayed.
+        */
+       node = fdtdec_next_compatible(blob, 0, COMPAT_SANDBOX_LCD_SDL);
+       if (node >= 0) {
+               xres = fdtdec_get_int(blob, node, "xres", LCD_MAX_WIDTH);
+               yres = fdtdec_get_int(blob, node, "yres", LCD_MAX_HEIGHT);
+               if (xres < 0 || xres > LCD_MAX_WIDTH) {
+                       xres = LCD_MAX_WIDTH;
+                       ret = -EINVAL;
+               }
+               if (yres < 0 || yres > LCD_MAX_HEIGHT) {
+                       yres = LCD_MAX_HEIGHT;
+                       ret = -EINVAL;
+               }
+       }
+
+       panel_info.vl_col = xres;
+       panel_info.vl_row = yres;
+       panel_info.vl_bpix = LCD_COLOR16;
+
+       return ret;
+}
index bcd2ee5f9c44871e0f8771bb17f8de31ab272ec7..6e859ce64cff4ef60f704906e4fd09ea72f65882 100644 (file)
@@ -89,6 +89,7 @@ enum fdt_compat_id {
        COMPAT_INFINEON_SLB9645_TPM,    /* Infineon SLB9645 TPM */
        COMPAT_SAMSUNG_EXYNOS5_I2C,     /* Exynos5 High Speed I2C Controller */
        COMPAT_SANDBOX_HOST_EMULATION,  /* Sandbox emulation of a function */
+       COMPAT_SANDBOX_LCD_SDL,         /* Sandbox LCD emulation with SDL */
 
        COMPAT_COUNT,
 };
index d06d6f10720e751020705d04dde5eb2267276af0..5f84cd3c5b2ccad57c78fdf01419f0e50e2b11db 100644 (file)
@@ -313,6 +313,9 @@ int lcd_get_size(int *line_length);
 int lcd_dt_simplefb_add_node(void *blob);
 int lcd_dt_simplefb_enable_existing_node(void *blob);
 
+/* Update the LCD / flush the cache */
+void lcd_sync(void);
+
 /************************************************************************/
 /* ** BITMAP DISPLAY SUPPORT                                           */
 /************************************************************************/
index e0b8927ac814c24765b70521535f5d00b0666da7..f65ab4f58fffac63f04d0945dc41a9990d80b2d0 100644 (file)
@@ -62,6 +62,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
        COMPAT(INFINEON_SLB9645_TPM, "infineon,slb9645-tpm"),
        COMPAT(SAMSUNG_EXYNOS5_I2C, "samsung,exynos5-hsi2c"),
        COMPAT(SANDBOX_HOST_EMULATION, "sandbox,host-emulation"),
+       COMPAT(SANDBOX_LCD_SDL, "sandbox,lcd-sdl"),
 };
 
 const char *fdtdec_get_compatible(enum fdt_compat_id id)