如何在Yocto Linux设备树中添加双LCD面板并通过Barebox切换启用
解决Yocto设备树多显示屏切换的Label重复与连接错误问题
问题根源分析
- Duplicate label 'panel_in'错误:设备树中每个节点的label必须唯一,两个
panel-lcd节点的endpoint共用panel_in标签,违反DTS语法规则。 - Cannot connect bridge: -19错误:错误码
-19对应ENODEV,内核无法找到LCD控制器(lcdif)与启用面板的有效连接路径。修改label后,lcdif的remote-endpoint仍指向固定旧标签,切换面板时未同步更新该指向,导致连接失败。
解决方案步骤
1. 修改设备树,给每个面板的Endpoint分配唯一Label
修改DTSI文件,为两个面板的endpoint设置唯一标识,同时让lcdif默认指向其中一个面板(后续由Barebox动态修改):
/ { panel-lcd-tn { compatible = "powertip,ph320240t023_iha"; backlight = <&backlight_peb>; status = "disabled"; port { panel_in_tn: endpoint { remote-endpoint = <&display_out>; }; }; }; panel-lcd-ips { compatible = "powertip,ph320240t028_zha"; backlight = <&backlight_peb>; status = "disabled"; port { panel_in_ips: endpoint { remote-endpoint = <&display_out>; }; }; }; ... }; &lcdif { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_lcdif_dat>; status = "okay"; // 提前启用控制器,避免重复修改 port { display_out: endpoint { remote-endpoint = <&panel_in_tn>; // 默认指向TN面板 }; }; };
2. 在Barebox中添加动态切换逻辑
切换面板时,不仅要修改面板的status,还要同步更新lcdif的remote-endpoint指向当前启用的面板。以下是两种实现方式:
方式一:C语言Fixup函数
#include <of.h> static int panel_fixup(struct device_node *root, void *ctx) { struct device_node *tn_panel, *ips_panel, *lcdif, *lcdif_ep; const char *panel_type = ctx; // 获取目标节点 tn_panel = of_find_node_by_path(root, "/panel-lcd-tn"); ips_panel = of_find_node_by_path(root, "/panel-lcd-ips"); lcdif = of_find_node_by_path(root, "/soc/aips-bus@02100000/lcdif@021c8000"); if (!tn_panel || !ips_panel || !lcdif) return -EINVAL; lcdif_ep = of_get_child_by_name(lcdif, "port"); if (lcdif_ep) lcdif_ep = of_get_child_by_name(lcdif_ep, "endpoint"); // 根据选择切换面板并更新连接 if (!strcmp(panel_type, "tn")) { of_fixup_status(tn_panel, "okay"); of_fixup_status(ips_panel, "disabled"); if (lcdif_ep) of_property_set_string(lcdif_ep, "remote-endpoint", "panel_in_tn"); } else if (!strcmp(panel_type, "ips")) { of_fixup_status(tn_panel, "disabled"); of_fixup_status(ips_panel, "okay"); if (lcdif_ep) of_property_set_string(lcdif_ep, "remote-endpoint", "panel_in_ips"); } return 0; } BAREBOX_FIXUP(panel_fixup, "panel-fixup", panel_fixup);
方式二:Barebox启动脚本命令行修改
# 切换到TN面板 fdt set /panel-lcd-tn status okay fdt set /panel-lcd-ips status disabled fdt set /soc/aips-bus@02100000/lcdif@021c8000/port/endpoint remote-endpoint <&panel_in_tn> # 切换到IPS面板 fdt set /panel-lcd-tn status disabled fdt set /panel-lcd-ips status okay fdt set /soc/aips-bus@02100000/lcdif@021c8000/port/endpoint remote-endpoint <&panel_in_ips>
3. 验证与调试
- 编译修改后的设备树与Barebox并烧录到设备
- 启动时通过指定参数(如
panel=tn)验证切换效果 - 可在Barebox中用
fdt print命令查看节点的status和remote-endpoint是否正确设置 - 内核启动后,通过
dmesg确认LCD控制器与面板的连接状态
内容的提问来源于stack exchange,提问作者Adrian
相关产品推荐
相关产品推荐

