when i use gd->fdt_blob and fdt_status_okay() to modyfy fdt in uboot, may case rockchip display driver can not found props in subnode of '/display-subsystem/route'
here what i do in uboot, and i will call lt8911_fixup_dts() before display driver init:
static int lt8911_fixup_dts(struct udevice *dev)
{
struct lt8911_plat *plat = dev_get_platdata(dev);
ofnode dsi_node, vp_node;
ofnode port, dsi_ports, ep;
const struct device_node *dsi_devnode, *vp_devnode;
const struct device_node *ep_devnode;
const char *dsi_path, *vp_path;
const void *blob = gd->fdt_blob;
int offset, ep_offset;
u32 reg, ep_reg;
debug("%s\n", __func__);
if(plat->use_lt8911_bridge) {
dsi_node = ofnode_path("/dsi@fe070000");
vp_node = ofnode_path("/video-phy@fe860000");
if (!ofnode_valid(dsi_node) | !ofnode_valid(vp_node))
return -ENODEV;
dsi_devnode = ofnode_to_np(dsi_node);
vp_devnode = ofnode_to_np(vp_node);
dsi_ports = ofnode_find_subnode(dsi_node, "ports");
if (!ofnode_valid(dsi_ports))
return -ENODEV;
ofnode_for_each_subnode(port, dsi_ports) {
if (ofnode_read_u32(port, "reg", ®))
continue;
if (reg != PORT_DIR_IN)
continue;
debug("port name:%s, reg:%d\n", port.np->full_name, reg);
//dsi@fe070000/ports/port@0
ofnode_for_each_subnode(ep, port) {
if(ofnode_read_u32(ep, "reg", &ep_reg)) {
continue;
}
if(ep_reg != DSI_IN_VP1)
continue;
ep_devnode = ofnode_to_np(ep);
ep_offset = fdt_path_offset(blob, ep_devnode->full_name);
if(ep_offset < 0) {
printf("get dsi0_in_vp1 node offset failed:%s\n", fdt_strerror(ep_offset));
return -1;
}
printf("dsi1_in_vp1:%s, reg:%d, offset:%d\n", ep_devnode->full_name, ep_reg, ep_offset);
fdt_status_okay((void *)blob, ep_offset); //&dsi1_in_vp1 { status = "okay"};
}
}
dsi_path = dsi_devnode->full_name;
offset = fdt_path_offset(blob, dsi_path);
if(offset < 0) {
printf("get dsi0 node offset failed:%s\n", fdt_strerror(offset));
return -1;
}
debug("dsi1:%s\n", dsi_path);
fdt_status_okay((void *)blob, offset); //&dsi1 { status = "okay"};
vp_path = vp_devnode->full_name;
offset = fdt_path_offset(blob, vp_path);
if(offset < 0) {
printf("get video_phy0 node offset failed:%s\n", fdt_strerror(offset));
return -1;
}
debug("video-phy1:%s\n", vp_path);
fdt_status_okay((void *)blob, offset); //&video_phy1 { status = "okay"};
} else {
dsi_node = ofnode_path("/dsi@fe060000");
vp_node = ofnode_path("/video-phy@fe850000");
if (!ofnode_valid(dsi_node) | !ofnode_valid(vp_node))
return -ENODEV;
dsi_devnode = ofnode_to_np(dsi_node);
vp_devnode = ofnode_to_np(vp_node);
dsi_ports = ofnode_find_subnode(dsi_node, "ports");
if (!ofnode_valid(dsi_ports))
return -ENODEV;
ofnode_for_each_subnode(port, dsi_ports) {
if (ofnode_read_u32(port, "reg", ®))
continue;
if (reg != PORT_DIR_IN)
continue;
debug("port name:%s, reg:%d\n", port.np->full_name, reg);
//dsi@fe060000/ports/port@0
ofnode_for_each_subnode(ep, port) {
if(ofnode_read_u32(ep, "reg", &ep_reg)) {
continue;
}
if(ep_reg != DSI_IN_VP1)
continue;
ep_devnode = ofnode_to_np(ep);
ep_offset = fdt_path_offset(blob, ep_devnode->full_name);
if(ep_offset < 0) {
printf("get dsi0_in_vp1 node offset failed:%s\n", fdt_strerror(ep_offset));
return -1;
}
debug("dsi0_in_vp1:%s, reg:%d\n", ep_devnode->full_name, ep_reg);
fdt_status_okay((void *)blob, ep_offset); //&dsi0_in_vp1 { status = "okay"};
}
}
dsi_path = dsi_devnode->full_name;
offset = fdt_path_offset(blob, dsi_path);
if(offset < 0) {
printf("get dsi0 node offset failed:%s\n", fdt_strerror(offset));
return -1;
}
debug("dsi0:%s\n", dsi_path);
fdt_status_okay((void *)blob, offset); //&dsi0 { status = "okay"};
vp_path = vp_devnode->full_name;
offset = fdt_path_offset(blob, vp_path);
if(offset < 0) {
printf("get video_phy0 node offset failed:%s\n", fdt_strerror(offset));
return -1;
}
debug("video-phy0:%s\n", vp_path);
fdt_status_okay((void *)blob, offset); //&video_phy0 { status = "okay"};
}
printf("lt8911 fixup dts success\n");
return 0;
}
here is code in rockchip_display.c:
/*
* traverse the following nodes:
* route-dsi0/route-dsi1/route-edp/route-hdmi/route-lvds/route-rgb
*/
route_node = ofnode_path("/display-subsystem/route");
ofnode_for_each_subnode(node, route_node) {
if (!ofnode_is_available(node))
continue;
phandle = ofnode_read_u32_default(node, "connect", -1);
if (phandle < 0) {
printf("Warn: can't find connect node's handle\n");
continue;
}
}
and the error log:
rockchip_display_probe enter
node path:/display-subsystem/route/route-dsi0, phandle:-1
Warn: can't find connect node's handle
node path:/display-subsystem/route/route-dsi1, phandle:-1
Warn: can't find connect node's handle
node path:/display-subsystem/route/route-edp, phandle:-1
Warn: can't find connect node's handle
node path:/display-subsystem/route/route-hdmi, phandle:-1
Warn: can't find connect node's handle
node path:/display-subsystem/route/route-lvds, phandle:-1
Warn: can't find connect node's handle
node path:/display-subsystem/route/route-rgb, phandle:-1
Warn: can't find connect node's handle
rockchip_display_probe enter
node path:/display-subsystem/route/route-dsi0, phandle:-1
Warn: can't find connect node's handle
node path:/display-subsystem/route/route-dsi1, phandle:-1
Warn: can't find connect node's handle
node path:/display-subsystem/route/route-edp, phandle:-1
Warn: can't find connect node's handle
node path:/display-subsystem/route/route-hdmi, phandle:-1
Warn: can't find connect node's handle
node path:/display-subsystem/route/route-lvds, phandle:-1
Warn: can't find connect node's handle
node path:/display-subsystem/route/route-rgb, phandle:-1
Warn: can't find connect node's handle
I would be very grateful if you could give me some help
in kernel dts, i turned off the following nodes by default:
&dsi0 {
status = "disabled";
};
&dsi0_in_vp0 {
status = "disabled";
};
&dsi0_in_vp1 {
status = "disabled";
};
&dsi1 {
status = "disabled";
};
&dsi1_in_vp0 {
status = "disabled";
};
&dsi1_in_vp1 {
status = "disabled";
};
&video_phy0 {
status = "disabled";
};
&video_phy1 {
status = "disabled";
};
And i want open these node(dsi1/dsi1_in_vp1/video_phy1) in uboot, so i call function of lt8911_fixup_dts(), in order for the following display link to work normal in uboot and kernel: vop->vp1->dsi1->lt8911->edp panel