diff mbox series

[U-Boot,v5,23/27] p2371-2180: Add support for framebuffer carveouts

Message ID 20190415093239.27509-24-thierry.reding@gmail.com
State Accepted
Delegated to: Tom Warren
Headers show
Series ARM: tegra: Miscalleneous improvements | expand

Commit Message

Thierry Reding April 15, 2019, 9:32 a.m. UTC
From: Thierry Reding <treding@nvidia.com>

If early firmware initialized the display hardware and the display
controllers are scanning out a framebuffer (e.g. a splash screen), make
sure to pass information about the memory location of that framebuffer
to the kernel before booting to avoid the kernel from using that memory
for the buddy allocator.

This same mechanism can also be used in the kernel to set up early SMMU
mappings and avoid SMMU faults caused by the display controller reading
from memory for which it has no mapping.

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Thierry Reding <treding@nvidia.com>
---
Changes in v4:
- add reviewed-by from Simon

 board/nvidia/p2371-2180/p2371-2180.c | 47 ++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)
diff mbox series

Patch

diff --git a/board/nvidia/p2371-2180/p2371-2180.c b/board/nvidia/p2371-2180/p2371-2180.c
index a444d692d7ea..4985302d6bc2 100644
--- a/board/nvidia/p2371-2180/p2371-2180.c
+++ b/board/nvidia/p2371-2180/p2371-2180.c
@@ -6,6 +6,7 @@ 
 
 #include <common.h>
 #include <environment.h>
+#include <fdtdec.h>
 #include <i2c.h>
 #include <linux/libfdt.h>
 #include <asm/arch/gpio.h>
@@ -138,9 +139,55 @@  static void ft_mac_address_setup(void *fdt)
 	}
 }
 
+static int ft_copy_carveout(void *dst, const void *src, const char *node)
+{
+	struct fdt_memory fb;
+	int err;
+
+	err = fdtdec_get_carveout(src, node, "memory-region", 0, &fb);
+	if (err < 0) {
+		if (err != -FDT_ERR_NOTFOUND)
+			printf("failed to get carveout for %s: %d\n", node,
+			       err);
+
+		return err;
+	}
+
+	err = fdtdec_set_carveout(dst, node, "memory-region", 0, "framebuffer",
+				  &fb);
+	if (err < 0) {
+		printf("failed to set carveout for %s: %d\n", node, err);
+		return err;
+	}
+
+	return 0;
+}
+
+static void ft_carveout_setup(void *fdt)
+{
+	const void *cboot_fdt = (const void *)cboot_boot_x0;
+	static const char * const nodes[] = {
+		"/host1x@50000000/dc@54200000",
+		"/host1x@50000000/dc@54240000",
+	};
+	unsigned int i;
+	int err;
+
+	for (i = 0; i < ARRAY_SIZE(nodes); i++) {
+		err = ft_copy_carveout(fdt, cboot_fdt, nodes[i]);
+		if (err < 0) {
+			if (err != -FDT_ERR_NOTFOUND)
+				printf("failed to copy carveout for %s: %d\n",
+				       nodes[i], err);
+			continue;
+		}
+	}
+}
+
 int ft_board_setup(void *fdt, bd_t *bd)
 {
 	ft_mac_address_setup(fdt);
+	ft_carveout_setup(fdt);
 
 	return 0;
 }