提交 6036dba1 编写于 作者: P Peng Fan

imx8m: disable nodes before kernel/mfgtool boot for fused part

To fused part, we need to disable nodes of dtb to let kernel boot.

To mfgtool, USB issue when using super-speed for mfgtool, temporally
work around the problem to use high-speed only.
Signed-off-by: NPeng Fan <peng.fan@nxp.com>
上级 2707faf0
......@@ -428,12 +428,298 @@ bool is_usb_boot(void)
}
#ifdef CONFIG_OF_SYSTEM_SETUP
bool check_fdt_new_path(void *blob)
{
const char *soc_path = "/soc@0";
int nodeoff;
nodeoff = fdt_path_offset(blob, soc_path);
if (nodeoff < 0)
return false;
return true;
}
static int disable_fdt_nodes(void *blob, const char *const nodes_path[], int size_array)
{
int i = 0;
int rc;
int nodeoff;
const char *status = "disabled";
for (i = 0; i < size_array; i++) {
nodeoff = fdt_path_offset(blob, nodes_path[i]);
if (nodeoff < 0)
continue; /* Not found, skip it */
printf("Found %s node\n", nodes_path[i]);
add_status:
rc = fdt_setprop(blob, nodeoff, "status", status, strlen(status) + 1);
if (rc) {
if (rc == -FDT_ERR_NOSPACE) {
rc = fdt_increase_size(blob, 512);
if (!rc)
goto add_status;
}
printf("Unable to update property %s:%s, err=%s\n",
nodes_path[i], "status", fdt_strerror(rc));
} else {
printf("Modify %s:%s disabled\n",
nodes_path[i], "status");
}
}
return 0;
}
#ifdef CONFIG_IMX8MQ
bool check_dcss_fused(void)
{
struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
struct fuse_bank *bank = &ocotp->bank[1];
struct fuse_bank1_regs *fuse =
(struct fuse_bank1_regs *)bank->fuse_regs;
u32 value = readl(&fuse->tester4);
if (value & 0x4000000)
return true;
return false;
}
static int disable_mipi_dsi_nodes(void *blob)
{
static const char * const nodes_path[] = {
"/mipi_dsi@30A00000",
"/mipi_dsi_bridge@30A00000",
"/dsi_phy@30A00300",
"/soc@0/bus@30800000/mipi_dsi@30a00000",
"/soc@0/bus@30800000/dphy@30a00300"
};
return disable_fdt_nodes(blob, nodes_path, ARRAY_SIZE(nodes_path));
}
static int disable_dcss_nodes(void *blob)
{
static const char * const nodes_path[] = {
"/dcss@0x32e00000",
"/dcss@32e00000",
"/hdmi@32c00000",
"/hdmi_cec@32c33800",
"/hdmi_drm@32c00000",
"/display-subsystem",
"/sound-hdmi",
"/sound-hdmi-arc",
"/soc@0/bus@32c00000/display-controller@32e00000",
"/soc@0/bus@32c00000/hdmi@32c00000",
};
return disable_fdt_nodes(blob, nodes_path, ARRAY_SIZE(nodes_path));
}
static int check_mipi_dsi_nodes(void *blob)
{
static const char * const lcdif_path[] = {
"/lcdif@30320000",
"/soc@0/bus@30000000/lcdif@30320000"
};
static const char * const mipi_dsi_path[] = {
"/mipi_dsi@30A00000",
"/soc@0/bus@30800000/mipi_dsi@30a00000"
};
static const char * const lcdif_ep_path[] = {
"/lcdif@30320000/port@0/mipi-dsi-endpoint",
"/soc@0/bus@30000000/lcdif@30320000/port@0/endpoint"
};
static const char * const mipi_dsi_ep_path[] = {
"/mipi_dsi@30A00000/port@1/endpoint",
"/soc@0/bus@30800000/mipi_dsi@30a00000/ports/port@0/endpoint"
};
int lookup_node;
int nodeoff;
bool new_path = check_fdt_new_path(blob);
int i = new_path ? 1 : 0;
nodeoff = fdt_path_offset(blob, lcdif_path[i]);
if (nodeoff < 0 || !fdtdec_get_is_enabled(blob, nodeoff)) {
/*
* If can't find lcdif node or lcdif node is disabled,
* then disable all mipi dsi, since they only can input
* from DCSS
*/
return disable_mipi_dsi_nodes(blob);
}
nodeoff = fdt_path_offset(blob, mipi_dsi_path[i]);
if (nodeoff < 0 || !fdtdec_get_is_enabled(blob, nodeoff))
return 0;
nodeoff = fdt_path_offset(blob, lcdif_ep_path[i]);
if (nodeoff < 0) {
/*
* If can't find lcdif endpoint, then disable all mipi dsi,
* since they only can input from DCSS
*/
return disable_mipi_dsi_nodes(blob);
}
lookup_node = fdtdec_lookup_phandle(blob, nodeoff, "remote-endpoint");
nodeoff = fdt_path_offset(blob, mipi_dsi_ep_path[i]);
if (nodeoff > 0 && nodeoff == lookup_node)
return 0;
return disable_mipi_dsi_nodes(blob);
}
#endif
int disable_vpu_nodes(void *blob)
{
static const char * const nodes_path_8mq[] = {
"/vpu@38300000",
"/soc@0/vpu@38300000"
};
static const char * const nodes_path_8mm[] = {
"/vpu_g1@38300000",
"/vpu_g2@38310000",
"/vpu_h1@38320000"
};
static const char * const nodes_path_8mp[] = {
"/vpu_g1@38300000",
"/vpu_g2@38310000",
"/vpu_vc8000e@38320000"
};
if (is_imx8mq())
return disable_fdt_nodes(blob, nodes_path_8mq, ARRAY_SIZE(nodes_path_8mq));
else if (is_imx8mm())
return disable_fdt_nodes(blob, nodes_path_8mm, ARRAY_SIZE(nodes_path_8mm));
else if (is_imx8mp())
return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
else
return -EPERM;
}
int disable_gpu_nodes(void *blob)
{
static const char * const nodes_path_8mn[] = {
"/gpu@38000000"
};
return disable_fdt_nodes(blob, nodes_path_8mn, ARRAY_SIZE(nodes_path_8mn));
}
int disable_npu_nodes(void *blob)
{
static const char * const nodes_path_8mp[] = {
"/vipsi@38500000"
};
return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
}
int disable_isp_nodes(void *blob)
{
static const char * const nodes_path_8mp[] = {
"/soc@0/bus@32c00000/camera/isp@32e10000",
"/soc@0/bus@32c00000/camera/isp@32e20000"
};
return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
}
int disable_dsp_nodes(void *blob)
{
static const char * const nodes_path_8mp[] = {
"/dsp@3b6e8000"
};
return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
}
static int disable_cpu_nodes(void *blob, u32 disabled_cores)
{
static const char * const nodes_path[] = {
"/cpus/cpu@1",
"/cpus/cpu@2",
"/cpus/cpu@3",
};
u32 i = 0;
int rc;
int nodeoff;
if (disabled_cores > 3)
return -EINVAL;
i = 3 - disabled_cores;
for (; i < 3; i++) {
nodeoff = fdt_path_offset(blob, nodes_path[i]);
if (nodeoff < 0)
continue; /* Not found, skip it */
debug("Found %s node\n", nodes_path[i]);
rc = fdt_del_node(blob, nodeoff);
if (rc < 0) {
printf("Unable to delete node %s, err=%s\n",
nodes_path[i], fdt_strerror(rc));
} else {
printf("Delete node %s\n", nodes_path[i]);
}
}
return 0;
}
int ft_system_setup(void *blob, bd_t *bd)
{
#ifdef CONFIG_IMX8MQ
int i = 0;
int rc;
int nodeoff;
if (get_boot_device() == USB_BOOT) {
disable_dcss_nodes(blob);
bool new_path = check_fdt_new_path(blob);
int v = new_path ? 1 : 0;
static const char * const usb_dwc3_path[] = {
"/usb@38100000/dwc3",
"/soc@0/usb@38100000"
};
nodeoff = fdt_path_offset(blob, usb_dwc3_path[v]);
if (nodeoff >= 0) {
const char *speed = "high-speed";
printf("Found %s node\n", usb_dwc3_path[v]);
usb_modify_speed:
rc = fdt_setprop(blob, nodeoff, "maximum-speed", speed, strlen(speed) + 1);
if (rc) {
if (rc == -FDT_ERR_NOSPACE) {
rc = fdt_increase_size(blob, 512);
if (!rc)
goto usb_modify_speed;
}
printf("Unable to set property %s:%s, err=%s\n",
usb_dwc3_path[v], "maximum-speed", fdt_strerror(rc));
} else {
printf("Modify %s:%s = %s\n",
usb_dwc3_path[v], "maximum-speed", speed);
}
} else {
printf("Can't found %s node\n", usb_dwc3_path[v]);
}
}
/* Disable the CPU idle for A0 chip since the HW does not support it */
if (is_soc_rev(CHIP_REV_1_0)) {
static const char * const nodes_path[] = {
......@@ -464,6 +750,53 @@ int ft_system_setup(void *blob, bd_t *bd)
}
}
if (is_imx8mql()) {
disable_vpu_nodes(blob);
if (check_dcss_fused()) {
printf("DCSS is fused\n");
disable_dcss_nodes(blob);
check_mipi_dsi_nodes(blob);
}
}
if (is_imx8md())
disable_cpu_nodes(blob, 2);
#elif defined(CONFIG_IMX8MM)
if (is_imx8mml() || is_imx8mmdl() || is_imx8mmsl())
disable_vpu_nodes(blob);
if (is_imx8mmd() || is_imx8mmdl())
disable_cpu_nodes(blob, 2);
else if (is_imx8mms() || is_imx8mmsl())
disable_cpu_nodes(blob, 3);
#elif defined(CONFIG_IMX8MN)
if (is_imx8mnl() || is_imx8mndl() || is_imx8mnsl())
disable_gpu_nodes(blob);
if (is_imx8mnd() || is_imx8mndl())
disable_cpu_nodes(blob, 2);
else if (is_imx8mns() || is_imx8mnsl())
disable_cpu_nodes(blob, 3);
#elif defined(CONFIG_IMX8MP)
if (is_imx8mpl() || is_imx8mp7())
disable_vpu_nodes(blob);
if (is_imx8mpl() || is_imx8mp6() || is_imx8mp5())
disable_npu_nodes(blob);
if (is_imx8mpl() || is_imx8mp5())
disable_isp_nodes(blob);
if (is_imx8mpl() || is_imx8mp7() || is_imx8mp6() || is_imx8mp5())
disable_dsp_nodes(blob);
if (is_imx8mpd())
disable_cpu_nodes(blob, 2);
#endif
return 0;
}
#endif
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册