sunxi: video: Do not use CONFIG_SYS_MEM_TOP_HIDE for the framebuffer
authorHans de Goede <hdegoede@redhat.com>
Mon, 2 Feb 2015 16:13:29 +0000 (17:13 +0100)
committerHans de Goede <hdegoede@redhat.com>
Mon, 16 Feb 2015 18:40:59 +0000 (19:40 +0100)
Do not use CONFIG_SYS_MEM_TOP_HIDE for the framebuffer, instead override
board_get_usable_ram_top to make sure that u-boot is not relocated into the
area where we want to use the framebuffer, and patch the devicetree from
sunxi_simplefb_setup() to tell the kernel to not touch the framebuffer.

This makes u-boot properly see the framebuffer as dram, and initalize the
level 2 cache for it, fixing the very slow cfb scrolling problem.

As an added bonus this stops us from reserving the framebuffer when simplefb
is not used because an older kernel is booted, or hdp is used and no hdmi
cable was plugged in, freeing up the memory for kernel use in these cases.

Reported-by: Siarhei Siamashka <siarhei.siamashka@gmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Ian Campbell <ijc@hellion.org.uk>
drivers/video/sunxi_display.c
include/configs/sunxi-common.h

index f5f24fc020bd793d2e1de7914f99d032e55a5743..cd5963a75141d1f10722091688023a556f12e22a 100644 (file)
@@ -1060,6 +1060,11 @@ static const char *sunxi_get_mon_desc(enum sunxi_monitor monitor)
        return NULL; /* never reached */
 }
 
+ulong board_get_usable_ram_top(ulong total_size)
+{
+       return gd->ram_top - CONFIG_SUNXI_MAX_FB_SIZE;
+}
+
 void *video_hw_init(void)
 {
        static GraphicDevice *graphic_device = &sunxi_display.graphic_device;
@@ -1076,7 +1081,7 @@ void *video_hw_init(void)
        memset(&sunxi_display, 0, sizeof(struct sunxi_display));
 
        printf("Reserved %dkB of RAM for Framebuffer.\n",
-              CONFIG_SUNXI_FB_SIZE >> 10);
+              CONFIG_SUNXI_MAX_FB_SIZE >> 10);
        gd->fb_base = gd->ram_top;
 
        video_get_ctfb_res_modes(RES_MODE_1024x768, 24, &mode,
@@ -1194,6 +1199,7 @@ int sunxi_simplefb_setup(void *blob)
 {
        static GraphicDevice *graphic_device = &sunxi_display.graphic_device;
        int offset, ret;
+       u64 start, size;
        const char *pipeline = NULL;
 
 #ifdef CONFIG_MACH_SUN4I
@@ -1237,6 +1243,20 @@ int sunxi_simplefb_setup(void *blob)
                return 0; /* Keep older kernels working */
        }
 
+       /*
+        * Do not report the framebuffer as free RAM to the OS, note we cannot
+        * use fdt_add_mem_rsv() here, because then it is still seen as RAM,
+        * and e.g. Linux refuses to iomap RAM on ARM, see:
+        * linux/arch/arm/mm/ioremap.c around line 301.
+        */
+       start = gd->bd->bi_dram[0].start;
+       size = gd->bd->bi_dram[0].size - CONFIG_SUNXI_MAX_FB_SIZE;
+       ret = fdt_fixup_memory_banks(blob, &start, &size, 1);
+       if (ret) {
+               eprintf("Cannot setup simplefb: Error reserving memory\n");
+               return ret;
+       }
+
        ret = fdt_setup_simplefb_node(blob, offset, gd->fb_base,
                        graphic_device->winSizeX, graphic_device->winSizeY,
                        graphic_device->winSizeX * graphic_device->gdfBytesPP,
index cea52dbf7b7e396542af618bc754c486107c4382..33c06146c6d3f1d8e366fefd4d2abbd4c51d8550 100644 (file)
 
 #ifdef CONFIG_VIDEO
 /*
- * The amount of RAM that is reserved for the FB. This will not show up as
- * RAM to the kernel, but will be reclaimed by a KMS driver in future.
+ * The amount of RAM to keep free at the top of RAM when relocating u-boot,
+ * to use as framebuffer. This must be a multiple of 4096.
  */
-#define CONFIG_SUNXI_FB_SIZE (9 << 20)
+#define CONFIG_SUNXI_MAX_FB_SIZE (9 << 20)
 
 /* Do we want to initialize a simple FB? */
 #define CONFIG_VIDEO_DT_SIMPLEFB
 /* stop x86 thinking in cfbconsole from trying to init a pc keyboard */
 #define CONFIG_VGA_AS_SINGLE_DEVICE
 
-#define CONFIG_SYS_MEM_TOP_HIDE ((CONFIG_SUNXI_FB_SIZE + 0xFFF) & ~0xFFF)
-
 /* To be able to hook simplefb into dt */
 #ifdef CONFIG_VIDEO_DT_SIMPLEFB
 #define CONFIG_OF_BOARD_SETUP