blob: 9478f605441fe5251d188b05cc97cf1032cd473a [file] [log] [blame]
Emanuele Ghidoli73bc1882023-07-14 17:23:08 +02001// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright 2023 Toradex - https://www.toradex.com/
4 */
5
6#include "common.h"
7#include <dm.h>
8#include <fdt_support.h>
9#include <linux/soc/ti/ti_sci_protocol.h>
10
11static int fdt_fixup_msmc_ram(void *blob, char *parent_path, char *node_name)
12{
13 u64 msmc_start = 0, msmc_end = 0, msmc_size, reg[2];
14 struct ti_sci_handle *ti_sci = get_ti_sci_handle();
15 int ret, node, subnode, len, prev_node;
16 u32 range[4], addr, size;
17 const fdt32_t *sub_reg;
18
19 ti_sci->ops.core_ops.query_msmc(ti_sci, &msmc_start, &msmc_end);
20 msmc_size = msmc_end - msmc_start + 1;
21 debug("%s: msmc_start = 0x%llx, msmc_size = 0x%llx\n", __func__,
22 msmc_start, msmc_size);
23
24 /* find or create "msmc_sram node */
25 ret = fdt_path_offset(blob, parent_path);
26 if (ret < 0)
27 return ret;
28
29 node = fdt_find_or_add_subnode(blob, ret, node_name);
30 if (node < 0)
31 return node;
32
33 ret = fdt_setprop_string(blob, node, "compatible", "mmio-sram");
34 if (ret < 0)
35 return ret;
36
37 reg[0] = cpu_to_fdt64(msmc_start);
38 reg[1] = cpu_to_fdt64(msmc_size);
39 ret = fdt_setprop(blob, node, "reg", reg, sizeof(reg));
40 if (ret < 0)
41 return ret;
42
43 fdt_setprop_cell(blob, node, "#address-cells", 1);
44 fdt_setprop_cell(blob, node, "#size-cells", 1);
45
46 range[0] = 0;
47 range[1] = cpu_to_fdt32(msmc_start >> 32);
48 range[2] = cpu_to_fdt32(msmc_start & 0xffffffff);
49 range[3] = cpu_to_fdt32(msmc_size);
50 ret = fdt_setprop(blob, node, "ranges", range, sizeof(range));
51 if (ret < 0)
52 return ret;
53
54 subnode = fdt_first_subnode(blob, node);
55 prev_node = 0;
56
57 /* Look for invalid subnodes and delete them */
58 while (subnode >= 0) {
59 sub_reg = fdt_getprop(blob, subnode, "reg", &len);
60 addr = fdt_read_number(sub_reg, 1);
61 sub_reg++;
62 size = fdt_read_number(sub_reg, 1);
63 debug("%s: subnode = %d, addr = 0x%x. size = 0x%x\n", __func__,
64 subnode, addr, size);
65 if (addr + size > msmc_size ||
66 !strncmp(fdt_get_name(blob, subnode, &len), "sysfw", 5) ||
67 !strncmp(fdt_get_name(blob, subnode, &len), "l3cache", 7)) {
68 fdt_del_node(blob, subnode);
69 debug("%s: deleting subnode %d\n", __func__, subnode);
70 if (!prev_node)
71 subnode = fdt_first_subnode(blob, node);
72 else
73 subnode = fdt_next_subnode(blob, prev_node);
74 } else {
75 prev_node = subnode;
76 subnode = fdt_next_subnode(blob, prev_node);
77 }
78 }
79
80 return 0;
81}
82
83int fdt_fixup_msmc_ram_k3(void *blob)
84{
85 int ret;
86
87 ret = fdt_fixup_msmc_ram(blob, "/bus@100000", "sram@70000000");
88 if (ret < 0)
89 ret = fdt_fixup_msmc_ram(blob, "/interconnect@100000",
90 "sram@70000000");
91 if (ret)
92 printf("%s: fixing up msmc ram failed %d\n", __func__, ret);
93
94 return ret;
95}
Emanuele Ghidolid7e0b072023-07-14 17:23:10 +020096
97int fdt_del_node_path(void *blob, const char *path)
98{
99 int ret;
100 int nodeoff;
101
102 nodeoff = fdt_path_offset(blob, path);
103 if (nodeoff < 0)
104 return 0; /* Not found, skip it */
105
106 ret = fdt_del_node(blob, nodeoff);
107 if (ret < 0)
108 printf("Unable to delete node %s, err=%s\n", path, fdt_strerror(ret));
109 else
110 debug("Deleted node %s\n", path);
111
112 return ret;
113}