[24/26] imx8mn_bsh_smm_s2/pro: support simple frame-buffer

Message ID 20240913095622.72377-25-dario.binacchi@amarulasolutions.com
State New
Headers show
Series
  • Support display (and even more) on the BSH SMM S2/PRO boards
Related show

Commit Message

Dario Binacchi Sept. 13, 2024, 9:56 a.m. UTC
If you want to pass the frame-buffer to the kernel, the video output is
initialized by U-Boot, and kept by the kernel. The commit modifies the
device tree to be passed to the kernel just before launching it, to
prevent the kernel from reinitializing hardware that has already been
configured by the bootloader.

Co-developed-by: Michael Trimarchi <michael@amarulasolutions.com>
Signed-off-by: Michael Trimarchi <michael@amarulasolutions.com>
Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
---

 board/bsh/imx8mn_smm_s2/imx8mn_smm_s2.c | 99 +++++++++++++++++++++++++
 1 file changed, 99 insertions(+)

Patch

diff --git a/board/bsh/imx8mn_smm_s2/imx8mn_smm_s2.c b/board/bsh/imx8mn_smm_s2/imx8mn_smm_s2.c
index c99896873991..87eb4e7ed63e 100644
--- a/board/bsh/imx8mn_smm_s2/imx8mn_smm_s2.c
+++ b/board/bsh/imx8mn_smm_s2/imx8mn_smm_s2.c
@@ -5,6 +5,8 @@ 
 
 #include <asm/arch/sys_proto.h>
 #include <env.h>
+#include <fdt_simplefb.h>
+#include <fdt_support.h>
 
 int board_init(void)
 {
@@ -20,3 +22,100 @@  int board_late_init(void)
 
 	return 0;
 }
+
+#if (IS_ENABLED(CONFIG_OF_LIBFDT) && IS_ENABLED(CONFIG_FDT_SIMPLEFB) && \
+	IS_ENABLED(CONFIG_VIDEO))
+static void smm_s2_setup_simplefb(void *blob)
+{
+#define DT_BLK_CTRL_NODE_PATH "/soc@0/bus@32c00000/blk-ctrl@32e28000"
+#define DT_GPC_NODE_PATH "/soc@0/bus@30000000/gpc@303a0000"
+#define DT_MIPI_DSI_NODE_PATH "/soc@0/bus@32c00000/dsi@32e10000"
+#define DT_LCDIF_NODE_PATH "/soc@0/bus@32c00000/lcdif@32e00000"
+
+	const char *dt_addnode[][2] = {
+		{ DT_BLK_CTRL_NODE_PATH, "lcdif" },
+		{ DT_BLK_CTRL_NODE_PATH, "mipi-dsi" },
+	};
+
+	const char *dt_addprop[][2] = {
+		{ "/regulator-3v3-O2", "regulator-boot-on" },
+		{ "/regulator-3v3-O3", "regulator-boot-on" },
+		{ DT_GPC_NODE_PATH "/pgc/power-domain@3", "fsl,boot-on" },
+		{ DT_GPC_NODE_PATH "/pgc/power-domain@4", "fsl,boot-on" },
+		{ DT_BLK_CTRL_NODE_PATH "/lcdif", "fsl,boot-on" },
+		{ DT_BLK_CTRL_NODE_PATH "/mipi-dsi", "fsl,boot-on" },
+		{ DT_MIPI_DSI_NODE_PATH, "samsung,boot-on" },
+		{ DT_MIPI_DSI_NODE_PATH "/panel@0", "syna,boot-on" },
+		{ DT_LCDIF_NODE_PATH, "fsl,boot-on" },
+	};
+	const char *dt_delprop[][2] = {
+		{ DT_BLK_CTRL_NODE_PATH, "assigned-clock-rates" },
+		{ DT_GPC_NODE_PATH "/pgc/power-domain@3", "assigned-clock-rates" }, // pgc_dispmix
+		{ DT_LCDIF_NODE_PATH, "assigned-clock-rates" },
+	};
+	int i, ret, offset;
+
+	ret = fdt_simplefb_enable_and_mem_rsv(blob);
+	if (ret) {
+		printf("Failed to enable framebuffer DTS node\n");
+		return;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(dt_addnode); i++) {
+		const char *path = dt_addnode[i][0];
+		const char *node = dt_addnode[i][1];
+
+		offset = fdt_path_offset(blob, path);
+		if (offset < 0) {
+			printf("Missing node %s, err=%s\n", path,
+			       fdt_strerror(offset));
+			continue;
+		}
+
+		offset = fdt_find_or_add_subnode(blob, offset, node);
+		if (offset < 0)
+			printf("Failed to create node %s, err=%s\n", path,
+			       fdt_strerror(offset));
+		else
+			debug("Add node %s:%s\n", path, node);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(dt_addprop); i++) {
+		const char *path = dt_addprop[i][0];
+		const char *prop = dt_addprop[i][1];
+
+		ret = fdt_find_and_setprop(blob, path, prop, NULL, 0, 1);
+		if (ret < 0)
+			printf("Failed to add property %s:%s, err=%s\n", path, prop,
+			       fdt_strerror(ret));
+		else
+			debug("Add property %s:%s\n", path, prop);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(dt_delprop); i++) {
+		const char *path = dt_delprop[i][0];
+		const char *prop = dt_delprop[i][1];
+
+		offset = fdt_path_offset(blob, path);
+		if (offset < 0) {
+			printf("Missing node %s\n", path);
+			continue;
+		}
+
+		ret = fdt_delprop(blob, offset, prop);
+		if (ret < 0)
+			printf("Failed to delete property %s:%s\n", path, prop);
+		else
+			debug("Delete property %s:%s\n", path, prop);
+	}
+}
+#endif
+
+int ft_board_setup(void *blob, struct bd_info *bd)
+{
+	if (IS_ENABLED(CONFIG_OF_LIBFDT) && IS_ENABLED(CONFIG_FDT_SIMPLEFB) &&
+	    IS_ENABLED(CONFIG_VIDEO))
+		smm_s2_setup_simplefb(blob);
+
+	return 0;
+}