mirror of
https://github.com/AsahiLinux/u-boot
synced 2025-03-17 23:37:01 +00:00
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: Peng Fan <peng.fan@nxp.com>
This commit is contained in:
parent
2707faf01f
commit
6036dba1c8
1 changed files with 334 additions and 1 deletions
|
@ -428,11 +428,297 @@ bool is_usb_boot(void)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_OF_SYSTEM_SETUP
|
||||
int ft_system_setup(void *blob, bd_t *bd)
|
||||
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)) {
|
||||
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue