[27/29] bsh: imx8mn-smm-s2/pro: support simple frame-buffer

Message ID 20240903153100.918077-27-dario.binacchi@amarulasolutions.com
State New
Headers show
Series
  • [01/29] clk: Propagate clk_set_rate() if CLK_SET_PARENT_RATE present for gate and mux
Related show

Commit Message

Dario Binacchi Sept. 3, 2024, 3:30 p.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: Dario Binacchi <dario.binacchi@amarulasolutions.com>
---
 board/bsh/imx8mn_smm_s2/imx8mn_smm_s2.c | 98 +++++++++++++++++++++++++
 1 file changed, 98 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..fe2f91b82a2c 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,99 @@  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;
+}