From 5a474f4e94a479df5a9626932bab41db46853ecf Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Wed, 30 Nov 2016 12:11:16 +0530 Subject: video: dcu: fix framebuffer to the end of memory 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") Signed-off-by: Sanchayan Maity Signed-off-by: Stefan Agner --- board/toradex/colibri_vf/colibri_vf.c | 7 ++++++ configs/colibri_vf_defconfig | 1 + drivers/video/fsl_dcu_fb.c | 47 ++++++++++++++++++++++++++++++++--- include/configs/colibri_vf.h | 4 ++- include/fsl_dcu_fb.h | 1 + scripts/config_whitelist.txt | 1 + 6 files changed, 57 insertions(+), 4 deletions(-) diff --git a/board/toradex/colibri_vf/colibri_vf.c b/board/toradex/colibri_vf/colibri_vf.c index 3ba8b6b1cd..54afba25a5 100644 --- a/board/toradex/colibri_vf/colibri_vf.c +++ b/board/toradex/colibri_vf/colibri_vf.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -594,6 +595,7 @@ int checkboard(void) #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) int ft_board_setup(void *blob, bd_t *bd) { + int ret = 0; #ifdef CONFIG_FDT_FIXUP_PARTITIONS static struct node_info nodes[] = { { "fsl,vf610-nfc", MTD_DEV_TYPE_NAND, }, /* NAND flash */ @@ -603,6 +605,11 @@ int ft_board_setup(void *blob, bd_t *bd) puts(" Updating MTD partitions...\n"); fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes)); #endif +#ifdef CONFIG_FSL_DCU_FB + ret = fsl_dcu_fixedfb_setup(blob); + if (ret) + return ret; +#endif return ft_common_board_setup(blob, bd); } diff --git a/configs/colibri_vf_defconfig b/configs/colibri_vf_defconfig index 3ea6a8e885..975e419232 100644 --- a/configs/colibri_vf_defconfig +++ b/configs/colibri_vf_defconfig @@ -26,6 +26,7 @@ CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y CONFIG_CMD_UBI=y CONFIG_OF_CONTROL=y +CONFIG_OF_BOARD_SETUP=y CONFIG_DM=y CONFIG_DFU_MMC=y CONFIG_DFU_NAND=y diff --git a/drivers/video/fsl_dcu_fb.c b/drivers/video/fsl_dcu_fb.c index 88db41041a..ed1aab3d2e 100644 --- a/drivers/video/fsl_dcu_fb.c +++ b/drivers/video/fsl_dcu_fb.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -79,6 +80,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 +271,19 @@ 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) { + info.screen_size = 0; + 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 +333,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; @@ -383,3 +399,28 @@ 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->bd->bi_dram[0].size - info.screen_size; + + /* + * Align size on section size (1 MiB). The Linux kernel would crash + * otherwise, this seems to be a limitation/bug of the Linux + * kernel currently (Linux ~4.0) + */ + size &= 0xfff00000; + ret = fdt_fixup_memory_banks(blob, &start, &size, 1); + if (ret) { + eprintf("Cannot setup fb: Error reserving memory\n"); + return ret; + } + + return 0; +} +#endif diff --git a/include/configs/colibri_vf.h b/include/configs/colibri_vf.h index c647132269..4f79fc8a99 100644 --- a/include/configs/colibri_vf.h +++ b/include/configs/colibri_vf.h @@ -13,6 +13,7 @@ #define __CONFIG_H #include +#include #define CONFIG_VF610 #define CONFIG_SYS_THUMB_BUILD @@ -48,6 +49,7 @@ #define CONFIG_SYS_FSL_DCU_LE #define CONFIG_SYS_DCU_ADDR DCU0_BASE_ADDR +#define CONFIG_FSL_DCU_MAX_FB_SIZE SZ_4M #define DCU_TOTAL_LAYER_NUM 64 #define DCU_LAYER_MAX_NUM 6 #endif @@ -202,7 +204,7 @@ * 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 diff --git a/include/fsl_dcu_fb.h b/include/fsl_dcu_fb.h index 42632984d3..67e29e74e6 100644 --- a/include/fsl_dcu_fb.h +++ b/include/fsl_dcu_fb.h @@ -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, diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index d8b40afbe8..30c9e5cbd8 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -1260,6 +1260,7 @@ CONFIG_FSL_CADMUS CONFIG_FSL_CORENET CONFIG_FSL_CPLD CONFIG_FSL_DCU_FB +CONFIG_FSL_DCU_MAX_FB_SIZE CONFIG_FSL_DCU_SII9022A CONFIG_FSL_DDR_BIST CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE -- cgit v1.2.3