blob: d20cb6973ac4c671115daf19d53a8b6b625b597e [file] [log] [blame]
Peng Fan9f779fa2019-08-26 08:11:56 +00001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright 2019 NXP
4 */
5
6#include <common.h>
7#include <asm/arch/sci/sci.h>
8#include <dm/ofnode.h>
9#include <fdt_support.h>
10
11DECLARE_GLOBAL_DATA_PTR;
12
13static bool check_owned_resource(sc_rsrc_t rsrc_id)
14{
15 bool owned;
16
17 owned = sc_rm_is_resource_owned(-1, rsrc_id);
18
19 return owned;
20}
21
22static int disable_fdt_node(void *blob, int nodeoffset)
23{
24 int rc, ret;
25 const char *status = "disabled";
26
27 do {
28 rc = fdt_setprop(blob, nodeoffset, "status", status,
29 strlen(status) + 1);
30 if (rc) {
31 if (rc == -FDT_ERR_NOSPACE) {
32 ret = fdt_increase_size(blob, 512);
33 if (ret)
34 return ret;
35 }
36 }
37 } while (rc == -FDT_ERR_NOSPACE);
38
39 return rc;
40}
41
42static void update_fdt_with_owned_resources(void *blob)
43{
44 /*
45 * Traverses the fdt nodes, check its power domain and use
46 * the resource id in the power domain for checking whether
47 * it is owned by current partition
48 */
49 struct fdtdec_phandle_args args;
50 int offset = 0, depth = 0;
51 u32 rsrc_id;
52 int rc, i;
53
54 for (offset = fdt_next_node(blob, offset, &depth); offset > 0;
55 offset = fdt_next_node(blob, offset, &depth)) {
56 debug("Node name: %s, depth %d\n",
57 fdt_get_name(blob, offset, NULL), depth);
58
59 if (!fdt_get_property(blob, offset, "power-domains", NULL)) {
60 debug(" - ignoring node %s\n",
61 fdt_get_name(blob, offset, NULL));
62 continue;
63 }
64
65 if (!fdtdec_get_is_enabled(blob, offset)) {
66 debug(" - ignoring node %s\n",
67 fdt_get_name(blob, offset, NULL));
68 continue;
69 }
70
71 i = 0;
72 while (true) {
73 rc = fdtdec_parse_phandle_with_args(blob, offset,
74 "power-domains",
75 "#power-domain-cells",
76 0, i++, &args);
77 if (rc == -ENOENT) {
78 break;
79 } else if (rc) {
80 printf("Parse power-domains of %s wrong: %d\n",
81 fdt_get_name(blob, offset, NULL), rc);
82 continue;
83 }
84
85 rsrc_id = args.args[0];
86
87 if (!check_owned_resource(rsrc_id)) {
88 rc = disable_fdt_node(blob, offset);
89 if (!rc) {
90 printf("Disable %s rsrc %u not owned\n",
91 fdt_get_name(blob, offset, NULL),
92 rsrc_id);
93 } else {
94 printf("Unable to disable %s, err=%s\n",
95 fdt_get_name(blob, offset, NULL),
96 fdt_strerror(rc));
97 }
98 }
99 }
100 }
101}
102
103int ft_system_setup(void *blob, bd_t *bd)
104{
105 update_fdt_with_owned_resources(blob);
106
107 return 0;
108}