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

Dario Binacchi
2024-09-13T10:01:21Z

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(+)

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;
+}
--
2.43.0