xref: /rk3399_ARM-atf/plat/amd/common/plat_fdt.c (revision 9cc15390326dbd3a3d4e89299643e1d5b08958f6)
1ea453871SMaheedhar Bollapalli /*
2ea453871SMaheedhar Bollapalli  * Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved.
3ea453871SMaheedhar Bollapalli  *
4ea453871SMaheedhar Bollapalli  * SPDX-License-Identifier: BSD-3-Clause
5ea453871SMaheedhar Bollapalli  */
6ea453871SMaheedhar Bollapalli #include <common/debug.h>
7ea453871SMaheedhar Bollapalli #include <common/fdt_fixup.h>
8ea453871SMaheedhar Bollapalli #include <common/fdt_wrappers.h>
9ea453871SMaheedhar Bollapalli #include <libfdt.h>
10ea453871SMaheedhar Bollapalli #include <platform_def.h>
11ea453871SMaheedhar Bollapalli 
12ea453871SMaheedhar Bollapalli #include <plat_fdt.h>
13e7dd086fSHarrison Mutai #ifdef TRANSFER_LIST
14ea453871SMaheedhar Bollapalli #include <plat_xfer_list.h>
15e7dd086fSHarrison Mutai #endif
16ea453871SMaheedhar Bollapalli 
17ea453871SMaheedhar Bollapalli #define FIT_CONFS_PATH	"/configurations"
18ea453871SMaheedhar Bollapalli 
19*59eaed03SMaheedhar Bollapalli static struct reserve_mem_range rsvnodes[MAX_RESERVE_ADDR_INDICES] = {};
20*59eaed03SMaheedhar Bollapalli static uint32_t rsv_count;
21*59eaed03SMaheedhar Bollapalli 
is_fit_image(void * dtb)22ea453871SMaheedhar Bollapalli static bool is_fit_image(void *dtb)
23ea453871SMaheedhar Bollapalli {
24ea453871SMaheedhar Bollapalli 	int64_t confs_noffset = 0;
25ea453871SMaheedhar Bollapalli 	bool status = true;
26ea453871SMaheedhar Bollapalli 
27ea453871SMaheedhar Bollapalli 	confs_noffset = fdt_path_offset(dtb, FIT_CONFS_PATH);
28ea453871SMaheedhar Bollapalli 
29ea453871SMaheedhar Bollapalli 	/* confs_noffset is only present on FIT image */
30ea453871SMaheedhar Bollapalli 	if (confs_noffset < 0) {
31ea453871SMaheedhar Bollapalli 		status = false;
32ea453871SMaheedhar Bollapalli 	}
33ea453871SMaheedhar Bollapalli 
34ea453871SMaheedhar Bollapalli 	return status;
35ea453871SMaheedhar Bollapalli }
36ea453871SMaheedhar Bollapalli 
is_valid_dtb(void * fdt)37ea453871SMaheedhar Bollapalli int32_t is_valid_dtb(void *fdt)
38ea453871SMaheedhar Bollapalli {
39ea453871SMaheedhar Bollapalli 	int32_t ret = 0;
40ea453871SMaheedhar Bollapalli 
41ea453871SMaheedhar Bollapalli 	ret = fdt_check_header(fdt);
42ea453871SMaheedhar Bollapalli 	if (ret != 0) {
43ea453871SMaheedhar Bollapalli 		ERROR("Can't read DT at %p\n", fdt);
44ea453871SMaheedhar Bollapalli 		goto error;
45ea453871SMaheedhar Bollapalli 	}
46ea453871SMaheedhar Bollapalli 
47ea453871SMaheedhar Bollapalli 	ret = fdt_open_into(fdt, fdt, XILINX_OF_BOARD_DTB_MAX_SIZE);
48ea453871SMaheedhar Bollapalli 	if (ret < 0) {
49ea453871SMaheedhar Bollapalli 		ERROR("Invalid Device Tree at %p: error %d\n", fdt, ret);
50ea453871SMaheedhar Bollapalli 		goto error;
51ea453871SMaheedhar Bollapalli 	}
52ea453871SMaheedhar Bollapalli 
53ea453871SMaheedhar Bollapalli 	if (is_fit_image(fdt)) {
54ea453871SMaheedhar Bollapalli 		WARN("FIT image detected, TF-A will not update DTB for DDR address space\n");
55ea453871SMaheedhar Bollapalli 		ret = -FDT_ERR_NOTFOUND;
56ea453871SMaheedhar Bollapalli 	}
57ea453871SMaheedhar Bollapalli error:
58ea453871SMaheedhar Bollapalli 	return ret;
59ea453871SMaheedhar Bollapalli }
60ea453871SMaheedhar Bollapalli 
61ea453871SMaheedhar Bollapalli /* TODO: Reserve TFA memory in DT through custom TL entry */
prepare_dtb(void)62ea453871SMaheedhar Bollapalli void prepare_dtb(void)
63ea453871SMaheedhar Bollapalli {
64ea453871SMaheedhar Bollapalli 
65ea453871SMaheedhar Bollapalli }
66ea453871SMaheedhar Bollapalli 
plat_retrieve_dt_addr(void)67ea453871SMaheedhar Bollapalli uintptr_t plat_retrieve_dt_addr(void)
68ea453871SMaheedhar Bollapalli {
69ea453871SMaheedhar Bollapalli 	void *dtb = NULL;
70ea453871SMaheedhar Bollapalli 
71ea453871SMaheedhar Bollapalli 	dtb = transfer_list_retrieve_dt_address();
72ea453871SMaheedhar Bollapalli 	if (dtb == NULL) {
73ea453871SMaheedhar Bollapalli 		WARN("TL header or DT entry is invalid\n");
74ea453871SMaheedhar Bollapalli 	}
75ea453871SMaheedhar Bollapalli 
76ea453871SMaheedhar Bollapalli 	return (uintptr_t)dtb;
77ea453871SMaheedhar Bollapalli }
78*59eaed03SMaheedhar Bollapalli 
get_reserved_entries_fdt(uint32_t * reserve_nodes)79*59eaed03SMaheedhar Bollapalli struct reserve_mem_range *get_reserved_entries_fdt(uint32_t *reserve_nodes)
80*59eaed03SMaheedhar Bollapalli {
81*59eaed03SMaheedhar Bollapalli 	struct reserve_mem_range *rsvmr = NULL;
82*59eaed03SMaheedhar Bollapalli 
83*59eaed03SMaheedhar Bollapalli 	if ((rsv_count > 0) && (reserve_nodes != NULL)) {
84*59eaed03SMaheedhar Bollapalli 		rsvmr = &rsvnodes[0];
85*59eaed03SMaheedhar Bollapalli 		*reserve_nodes = rsv_count;
86*59eaed03SMaheedhar Bollapalli 	}
87*59eaed03SMaheedhar Bollapalli 
88*59eaed03SMaheedhar Bollapalli 	return rsvmr;
89*59eaed03SMaheedhar Bollapalli }
90*59eaed03SMaheedhar Bollapalli 
91*59eaed03SMaheedhar Bollapalli /* TODO: Parse TL overlays for updated tf-a and op-tee reserved nodes */
retrieve_reserved_entries(void)92*59eaed03SMaheedhar Bollapalli uint32_t retrieve_reserved_entries(void)
93*59eaed03SMaheedhar Bollapalli {
94*59eaed03SMaheedhar Bollapalli 	uint32_t ret = 1;
95*59eaed03SMaheedhar Bollapalli 	void *dtb = NULL;
96*59eaed03SMaheedhar Bollapalli 	int offset, node;
97*59eaed03SMaheedhar Bollapalli 	uint32_t i = 0;
98*59eaed03SMaheedhar Bollapalli 	const fdt32_t *reg_prop;
99*59eaed03SMaheedhar Bollapalli 
100*59eaed03SMaheedhar Bollapalli 
101*59eaed03SMaheedhar Bollapalli 	/* Get DT blob address */
102*59eaed03SMaheedhar Bollapalli 	dtb = (void *)plat_retrieve_dt_addr();
103*59eaed03SMaheedhar Bollapalli 
104*59eaed03SMaheedhar Bollapalli 	/* Check if DT is valid */
105*59eaed03SMaheedhar Bollapalli 	if (is_valid_dtb(dtb) >= 0) {
106*59eaed03SMaheedhar Bollapalli 		/* Find reserved memory node */
107*59eaed03SMaheedhar Bollapalli 		offset = fdt_path_offset(dtb, "/reserved-memory");
108*59eaed03SMaheedhar Bollapalli 		if (offset >= 0) {
109*59eaed03SMaheedhar Bollapalli 
110*59eaed03SMaheedhar Bollapalli 			/* Parse subnodes of reserved-memory */
111*59eaed03SMaheedhar Bollapalli 			fdt_for_each_subnode(node, dtb, offset) {
112*59eaed03SMaheedhar Bollapalli 				if (fdt_getprop(dtb, node, "no-map", NULL) == NULL) {
113*59eaed03SMaheedhar Bollapalli 					continue;
114*59eaed03SMaheedhar Bollapalli 				}
115*59eaed03SMaheedhar Bollapalli 
116*59eaed03SMaheedhar Bollapalli 				if (rsv_count == MAX_RESERVE_ADDR_INDICES) {
117*59eaed03SMaheedhar Bollapalli 					break;
118*59eaed03SMaheedhar Bollapalli 				}
119*59eaed03SMaheedhar Bollapalli 
120*59eaed03SMaheedhar Bollapalli 				reg_prop = fdt_getprop(dtb, node, "reg", NULL);
121*59eaed03SMaheedhar Bollapalli 				if (reg_prop == NULL) {
122*59eaed03SMaheedhar Bollapalli 					INFO("No valid reg prop found for subnode\n");
123*59eaed03SMaheedhar Bollapalli 					continue;
124*59eaed03SMaheedhar Bollapalli 				}
125*59eaed03SMaheedhar Bollapalli 
126*59eaed03SMaheedhar Bollapalli 				rsvnodes[i].base = (((uint64_t)fdt32_to_cpu(reg_prop[0]) << 32) |
127*59eaed03SMaheedhar Bollapalli 						fdt32_to_cpu(reg_prop[1]));
128*59eaed03SMaheedhar Bollapalli 				rsvnodes[i].size = (((uint64_t)fdt32_to_cpu(reg_prop[2]) << 32) |
129*59eaed03SMaheedhar Bollapalli 						fdt32_to_cpu(reg_prop[3]));
130*59eaed03SMaheedhar Bollapalli 				i++;
131*59eaed03SMaheedhar Bollapalli 			}
132*59eaed03SMaheedhar Bollapalli 			ret = 0;
133*59eaed03SMaheedhar Bollapalli 			rsv_count = i;
134*59eaed03SMaheedhar Bollapalli 		}
135*59eaed03SMaheedhar Bollapalli 	}
136*59eaed03SMaheedhar Bollapalli 
137*59eaed03SMaheedhar Bollapalli 	return ret;
138*59eaed03SMaheedhar Bollapalli }
139