--- /dev/null
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <errno.h>
+#include <fdtdec.h>
+#include <malloc.h>
+#include <asm/arch/sys_proto.h>
+
+static void disable_thermal_cpu_nodes(void *blob, u32 num_disabled_cores, u32 max_cores)
+{
+ static const char * const thermal_path[] = {
+ "/thermal-zones/cpu-thermal/cooling-maps/map0"
+ };
+
+ int nodeoff, cnt, i, ret, j;
+ u32 num_le32 = max_cores * 3;
+ u32 *cooling_dev = (u32 *)malloc(num_le32 * sizeof(__le32));
+
+ if (!cooling_dev) {
+ printf("failed to alloc cooling dev\n");
+ return;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(thermal_path); i++) {
+ nodeoff = fdt_path_offset(blob, thermal_path[i]);
+ if (nodeoff < 0)
+ continue; /* Not found, skip it */
+
+ cnt = fdtdec_get_int_array_count(blob, nodeoff, "cooling-device",
+ cooling_dev, num_le32);
+ if (cnt < 0)
+ continue;
+
+ if (cnt != num_le32)
+ printf("Warning: %s, cooling-device count %d\n", thermal_path[i], cnt);
+
+ for (j = 0; j < cnt; j++)
+ cooling_dev[j] = cpu_to_fdt32(cooling_dev[j]);
+
+ ret = fdt_setprop(blob, nodeoff, "cooling-device", &cooling_dev,
+ sizeof(__le32) * (num_le32 - num_disabled_cores * 3));
+ if (ret < 0) {
+ printf("Warning: %s, cooling-device setprop failed %d\n",
+ thermal_path[i], ret);
+ continue;
+ }
+
+ printf("Update node %s, cooling-device prop\n", thermal_path[i]);
+ }
+
+ free(cooling_dev);
+}
+
+int disable_cpu_nodes(void *blob, const char * const *nodes_path, u32 num_disabled_cores,
+ u32 max_cores)
+{
+ u32 i = 0;
+ int rc;
+ int nodeoff;
+
+ if (max_cores == 0 || (num_disabled_cores > (max_cores - 1)))
+ return -EINVAL;
+
+ i = max_cores - num_disabled_cores;
+
+ for (; i < max_cores; 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]);
+ }
+ }
+
+ disable_thermal_cpu_nodes(blob, num_disabled_cores, max_cores);
+
+ return 0;
+}
return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
}
-static void disable_thermal_cpu_nodes(void *blob, u32 disabled_cores)
-{
- static const char * const thermal_path[] = {
- "/thermal-zones/cpu-thermal/cooling-maps/map0"
- };
-
- int nodeoff, cnt, i, ret, j;
- u32 cooling_dev[12];
-
- for (i = 0; i < ARRAY_SIZE(thermal_path); i++) {
- nodeoff = fdt_path_offset(blob, thermal_path[i]);
- if (nodeoff < 0)
- continue; /* Not found, skip it */
-
- cnt = fdtdec_get_int_array_count(blob, nodeoff, "cooling-device", cooling_dev, 12);
- if (cnt < 0)
- continue;
-
- if (cnt != 12)
- printf("Warning: %s, cooling-device count %d\n", thermal_path[i], cnt);
-
- for (j = 0; j < cnt; j++)
- cooling_dev[j] = cpu_to_fdt32(cooling_dev[j]);
-
- ret = fdt_setprop(blob, nodeoff, "cooling-device", &cooling_dev,
- sizeof(u32) * (12 - disabled_cores * 3));
- if (ret < 0) {
- printf("Warning: %s, cooling-device setprop failed %d\n",
- thermal_path[i], ret);
- continue;
- }
-
- printf("Update node %s, cooling-device prop\n", thermal_path[i]);
- }
-}
-
-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]);
- }
- }
-
- disable_thermal_cpu_nodes(blob, disabled_cores);
-
- return 0;
-}
-
static int cleanup_nodes_for_efi(void *blob)
{
static const char * const path[][2] = {
int ft_system_setup(void *blob, struct bd_info *bd)
{
+ static const char * const nodes_path[] = {
+ "/cpus/cpu@0",
+ "/cpus/cpu@1",
+ "/cpus/cpu@2",
+ "/cpus/cpu@3",
+ };
+
#ifdef CONFIG_IMX8MQ
int i = 0;
int rc;
/* 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[] = {
- "/cpus/cpu@0",
- "/cpus/cpu@1",
- "/cpus/cpu@2",
- "/cpus/cpu@3",
- };
-
for (i = 0; i < ARRAY_SIZE(nodes_path); i++) {
nodeoff = fdt_path_offset(blob, nodes_path[i]);
if (nodeoff < 0)
}
if (is_imx8md())
- disable_cpu_nodes(blob, 2);
+ disable_cpu_nodes(blob, nodes_path, 2, 4);
#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);
+ disable_cpu_nodes(blob, nodes_path, 2, 4);
else if (is_imx8mms() || is_imx8mmsl())
- disable_cpu_nodes(blob, 3);
+ disable_cpu_nodes(blob, nodes_path, 3, 4);
#elif defined(CONFIG_IMX8MN)
if (is_imx8mnl() || is_imx8mndl() || is_imx8mnsl())
#endif
if (is_imx8mnd() || is_imx8mndl() || is_imx8mnud())
- disable_cpu_nodes(blob, 2);
+ disable_cpu_nodes(blob, nodes_path, 2, 4);
else if (is_imx8mns() || is_imx8mnsl() || is_imx8mnus())
- disable_cpu_nodes(blob, 3);
+ disable_cpu_nodes(blob, nodes_path, 3, 4);
#elif defined(CONFIG_IMX8MP)
if (is_imx8mpul()) {
disable_dsp_nodes(blob);
if (is_imx8mpd())
- disable_cpu_nodes(blob, 2);
+ disable_cpu_nodes(blob, nodes_path, 2, 4);
#endif
cleanup_nodes_for_efi(blob);