Commit da636e4b8eda4698be6e2e53767cc1a598aadb0b

Authored by Ye Li
1 parent accea7eb04

MLK-20794-1 imx8: Change kernel FDT updating for fused parts

Before booting kernel, we check all nodes in kernel FDT whether they
are owned in our partition. If it is not owned, we will disable it in FDT.

For fused iMX8X 17x17 parts, like DC0 is disabled, SCFW only disable SC_R_DC_0,
other sub-modules in DC0 SS are still assign to our partition. Since DC0 is fused,
we actually can't access these sub-modules.

This patch changes the algorithm to check resources along the power domain tree to the
top node of that SS power domain. If any resource in the PD tree is not owned, we will
disable the peripheral node.
For example, the i2c0_mipi_lvds1 peripheral node, according to power domain tree,
we checks resources: SC_R_MIPI_1_I2C_0  -->  SC_R_MIPI_1  --> SC_R_DC_0. When SC_R_DC_0
is not owned, we will disable the i2c0_mipi_lvds1 peripheral node from FDT.

Signed-off-by: Ye Li <ye.li@nxp.com>

Showing 1 changed file with 49 additions and 30 deletions Side-by-side Diff

arch/arm/mach-imx/imx8/cpu.c
... ... @@ -895,6 +895,44 @@
895 895 return owned;
896 896 }
897 897  
  898 +static bool check_owned_resources_in_pd_tree(void *blob, int nodeoff,
  899 + unsigned int *unowned_rsrc)
  900 +{
  901 + unsigned int rsrc_id;
  902 + const fdt32_t *php;
  903 +
  904 + /* Search the ancestors nodes in current SS power-domain tree,
  905 + * if all ancestors' resources are owned, we can enable the node,
  906 + * otherwise any ancestor is not owned, we should disable the node.
  907 + */
  908 +
  909 + do {
  910 + php = fdt_getprop(blob, nodeoff, "power-domains", NULL);
  911 + if (!php) {
  912 + debug(" - ignoring no power-domains\n");
  913 + break;
  914 + }
  915 + nodeoff = fdt_node_offset_by_phandle(blob, fdt32_to_cpu(*php));
  916 +
  917 + rsrc_id = fdtdec_get_uint(blob, nodeoff, "reg", 0);
  918 + if (rsrc_id == SC_R_LAST) {
  919 + debug("%s's power domain use SC_R_LAST\n",
  920 + fdt_get_name(blob, nodeoff, NULL));
  921 + break;
  922 + }
  923 +
  924 + debug("power-domains node 0x%x, resource id %u\n", nodeoff, rsrc_id);
  925 +
  926 + if (!check_owned_resource(rsrc_id)) {
  927 + if (unowned_rsrc != NULL)
  928 + *unowned_rsrc = rsrc_id;
  929 + return false;
  930 + }
  931 + } while (fdt_node_check_compatible(blob, nodeoff, "nxp,imx8-pd"));
  932 +
  933 + return true;
  934 +}
  935 +
898 936 static int disable_fdt_node(void *blob, int nodeoffset)
899 937 {
900 938 int rc, ret;
901 939  
... ... @@ -1155,11 +1193,9 @@
1155 1193 * for checking whether it is owned by current partition
1156 1194 */
1157 1195  
1158   - int offset = 0, next_off, addr;
  1196 + int offset = 0, next_off;
1159 1197 int depth, next_depth;
1160 1198 unsigned int rsrc_id;
1161   - const fdt32_t *php;
1162   - const char *name;
1163 1199 int rc;
1164 1200  
1165 1201 for (offset = fdt_next_node(blob, offset, &depth); offset > 0;
1166 1202  
... ... @@ -1190,34 +1226,17 @@
1190 1226 continue;
1191 1227 }
1192 1228  
1193   - php = fdt_getprop(blob, offset, "power-domains", NULL);
1194   - if (!php) {
1195   - debug(" - ignoring no power-domains\n");
1196   - } else {
1197   - addr = fdt_node_offset_by_phandle(blob, fdt32_to_cpu(*php));
1198   - rsrc_id = fdtdec_get_uint(blob, addr, "reg", 0);
1199   -
1200   - if (rsrc_id == SC_R_LAST) {
1201   - name = fdt_get_name(blob, offset, NULL);
1202   - printf("%s's power domain use SC_R_LAST\n", name);
1203   - continue;
1204   - }
1205   -
1206   - debug("power-domains phandle 0x%x, addr 0x%x, resource id %u\n",
1207   - fdt32_to_cpu(*php), addr, rsrc_id);
1208   -
1209   - if (!check_owned_resource(rsrc_id)) {
1210   -
1211   - /* If the resource is not owned, disable it in FDT */
1212   - rc = disable_fdt_node(blob, offset);
1213   - if (!rc)
1214   - printf("Disable %s, resource id %u, pd phandle 0x%x\n",
1215   - fdt_get_name(blob, offset, NULL), rsrc_id, fdt32_to_cpu(*php));
1216   - else
1217   - printf("Unable to disable %s, err=%s\n",
1218   - fdt_get_name(blob, offset, NULL), fdt_strerror(rc));
1219   - }
  1229 + if (!check_owned_resources_in_pd_tree(blob, offset, &rsrc_id)) {
  1230 + /* If the resource is not owned, disable it in FDT */
  1231 + rc = disable_fdt_node(blob, offset);
  1232 + if (!rc)
  1233 + printf("Disable %s, resource id %u not owned\n",
  1234 + fdt_get_name(blob, offset, NULL), rsrc_id);
  1235 + else
  1236 + printf("Unable to disable %s, err=%s\n",
  1237 + fdt_get_name(blob, offset, NULL), fdt_strerror(rc));
1220 1238 }
  1239 +
1221 1240 }
1222 1241 }
1223 1242