video: dcu: fix framebuffer to the end of memory
authorStefan Agner <stefan.agner@toradex.com>
Wed, 22 Apr 2015 14:16:26 +0000 (16:16 +0200)
committerStefan Agner <stefan.agner@toradex.com>
Wed, 22 Apr 2015 14:16:26 +0000 (16:16 +0200)
Fix the framebuffer location to the very end of the available memory.
This allows to remove the area from available memory for the kernel,
which in turn allows to display the splash screen through the while
Linux kernel boot process.

Ideas has been taken from the sunxi display driver, e.g.
20779ec3a5 ("sunxi: video: Dynamically reserve framebuffer memory")

board/toradex/colibri_vf/colibri_vf.c
drivers/video/fsl_dcu_fb.c
include/configs/colibri_vf.h
include/fsl_dcu_fb.h

index aef8511aa988b606e71b8504979c1a443f4fa6d4..8cbc523145c870c4db3099fbb2b374b81d4df209 100644 (file)
@@ -17,6 +17,7 @@
 #include <asm/imx-common/boot_mode.h>
 #include <mmc.h>
 #include <fsl_esdhc.h>
+#include <fsl_dcu_fb.h>
 #include <miiphy.h>
 #include <netdev.h>
 #include <i2c.h>
@@ -462,3 +463,10 @@ int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name)
 
        return 0;
 }
+
+#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
+int ft_board_setup(void *blob, bd_t *bd)
+{
+       return fsl_dcu_fixedfb_setup(blob);
+}
+#endif
index 530656e19047b8c2177c544bc03992e2b11004e6..73285f55a92e4c3fb2a130c09abe5d3084fdccc3 100644 (file)
@@ -6,8 +6,10 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
+#include <asm/errno.h>
 #include <asm/io.h>
 #include <common.h>
+#include <fdt_support.h>
 #include <fsl_dcu_fb.h>
 #include <linux/fb.h>
 #include <malloc.h>
@@ -79,6 +81,8 @@
 #define BPP_24_RGB888                  5
 #define BPP_32_ARGB8888                        6
 
+DECLARE_GLOBAL_DATA_PTR;
+
 /*
  * This setting is used for the TWR_LCD_RGB card
  */
@@ -268,11 +272,16 @@ int fsl_dcu_init(unsigned int xres, unsigned int yres,
        struct dcu_reg *regs = (struct dcu_reg *)CONFIG_SYS_DCU_ADDR;
        unsigned int div, mode;
 
-       /* Memory allocation for framebuffer */
        info.screen_size =
                info.var.xres * info.var.yres * (info.var.bits_per_pixel / 8);
-       info.screen_base = (char *)memalign(ARCH_DMA_MINALIGN,
-                       roundup(info.screen_size, ARCH_DMA_MINALIGN));
+
+       if (info.screen_size > CONFIG_FSL_DCU_MAX_FB_SIZE)
+               return -ENOMEM;
+
+       /* Reserve framebuffer at the end of memory */
+       gd->fb_base = gd->bd->bi_dram[0].start +
+                     gd->bd->bi_dram[0].size - info.screen_size;
+       info.screen_base = (char *)gd->fb_base;
        memset(info.screen_base, 0, info.screen_size);
 
        reset_total_layers();
@@ -322,6 +331,11 @@ int fsl_dcu_init(unsigned int xres, unsigned int yres,
        return 0;
 }
 
+ulong board_get_usable_ram_top(ulong total_size)
+{
+       return gd->ram_top - CONFIG_FSL_DCU_MAX_FB_SIZE;
+}
+
 void *video_hw_init(void)
 {
        static GraphicDevice ctfb;
@@ -384,3 +398,21 @@ void *video_hw_init(void)
 
        return &ctfb;
 }
+
+#if defined(CONFIG_OF_BOARD_SETUP)
+int fsl_dcu_fixedfb_setup(void *blob)
+{
+       u64 start, size;
+       int ret;
+
+       start = gd->bd->bi_dram[0].start;
+       size = gd->fb_base - gd->bd->bi_dram[0].start;
+       ret = fdt_fixup_memory_banks(blob, &start, &size, 1);
+       if (ret) {
+               eprintf("Cannot setup fb: Error reserving memory\n");
+               return ret;
+       }
+
+       return 0;
+}
+#endif
index 007f09ebe34080899c9f8e3c01847ebcb2689d83..11a6eeac89272816a0cb851b4b7e91669ee2202b 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <asm/arch/imx-regs.h>
 #include <config_cmd_default.h>
+#include <linux/sizes.h>
 
 #define CONFIG_VF610
 #define CONFIG_SYS_THUMB_BUILD
@@ -34,6 +35,8 @@
 #define CONFIG_MXC_OCOTP
 #endif
 
+#define CONFIG_OF_BOARD_SETUP
+
 #define CONFIG_FSL_DCU_FB
 
 #ifdef CONFIG_FSL_DCU_FB
@@ -50,6 +53,7 @@
 
 #define CONFIG_SYS_FSL_DCU_LE
 #define CONFIG_SYS_DCU_ADDR            DCU0_BASE_ADDR
+#define CONFIG_FSL_DCU_MAX_FB_SIZE     (4 * SZ_1M)
 #define DCU_TOTAL_LAYER_NUM            64
 #define DCU_LAYER_MAX_NUM              6
 #endif
  * Stack sizes
  * The stack sizes are set up in start.S using the settings below
  */
-#define CONFIG_STACKSIZE               (128 * 1024)    /* regular stack */
+#define CONFIG_STACKSIZE               SZ_256K
 
 /* Physical memory map */
 #define CONFIG_NR_DRAM_BANKS           1
index 42632984d359df36e7b1ad2fa2260132459eaea4..67e29e74e62c72f76407a606d7ddbc4d17581bf7 100644 (file)
@@ -9,6 +9,7 @@
 
 int fsl_dcu_init(unsigned int xres, unsigned int yres,
                 unsigned int pixel_format);
+int fsl_dcu_fixedfb_setup(void *blob);
 
 /* Prototypes for external board-specific functions */
 int platform_dcu_init(unsigned int xres, unsigned int yres,