summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorStefan Agner <stefan.agner@toradex.com>2016-11-30 12:11:16 +0530
committerMarcel Ziswiler <marcel.ziswiler@toradex.com>2017-01-11 21:27:11 +0100
commit5a474f4e94a479df5a9626932bab41db46853ecf (patch)
treec8ad3bc987fcb0ea08240f182ccb26423f869c2e /drivers
parent4ee6eeea41c1ca6ec4255d5330fe7c7d1775eea6 (diff)
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 <maitysanchayan@gmail.com> Signed-off-by: Stefan Agner <stefan.agner@toradex.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/fsl_dcu_fb.c47
1 files changed, 44 insertions, 3 deletions
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 <asm/io.h>
#include <common.h>
+#include <fdt_support.h>
#include <fsl_dcu_fb.h>
#include <linux/fb.h>
#include <malloc.h>
@@ -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