xref: /rk3399_ARM-atf/plat/intel/soc/common/socfpga_dt.c (revision 10ecd58093a34e95e2dfad65b1180610f29397cc)
1 /*
2  * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
3  * Copyright (c) 2024-2025, Altera Corporation. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include <assert.h>
9 #include <errno.h>
10 
11 #include <arch_helpers.h>
12 #include <common/debug.h>
13 #include <common/fdt_wrappers.h>
14 #include <common/tbbr/tbbr_img_def.h>
15 #include <drivers/arm/gic_common.h>
16 #include <drivers/arm/gicv3.h>
17 #include <drivers/delay_timer.h>
18 #include <lib/mmio.h>
19 #include <lib/utils.h>
20 #include <libfdt.h>
21 #include <platform_def.h>
22 #include <tools_share/firmware_image_package.h>
23 
24 #include "socfpga_dt.h"
25 
26 static const void *fdt;
27 /*******************************************************************************
28  * This function checks device tree file with its header.
29  * Returns 0 on success and a negative FDT error code on failure.
30  ******************************************************************************/
31 int socfpga_dt_open_and_check(uintptr_t dt_addr, char *compatible_str)
32 {
33 	int ret = 0;
34 	int node = 1;
35 
36 	ret = fdt_check_header((void *)dt_addr);
37 
38 	if (ret != 0) {
39 		ERROR("SOCFPGA: FDT Header invalid\n");
40 		return ret;
41 	}
42 
43 	fdt = (const void *)dt_addr;
44 
45 	/* As libfdt use void *, we can't avoid this cast */
46 	const void *dtb = (void *)dt_addr;
47 
48 	/* Assert the node offset point to compatible property */
49 	node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
50 	if (node < 0) {
51 		ERROR("SOCFPGA: Can't find `%s` compatible in dtb\n",
52 						compatible_str);
53 		return node;
54 	}
55 
56 	NOTICE("SOCFPGA: Successfully open and check FDT\n");
57 
58 	return ret;
59 }
60 
61 int socfpga_dt_populate_gicv3_config(uintptr_t dt_addr, gicv3_driver_data_t *plat_driver_data)
62 {
63 	int err;
64 	int node;
65 	uintptr_t addr;
66 
67 	/* Necessary to work with libfdt APIs */
68 	const void *hw_config_dtb = (const void *)dt_addr;
69 	/*
70 	 * Find the offset of the node containing "arm,gic-v3" compatible property.
71 	 * Populating fconf strucutures dynamically is not supported for legacy
72 	 * systems which use GICv2 IP. Simply skip extracting GIC properties.
73 	 */
74 	node = fdt_node_offset_by_compatible(hw_config_dtb, -1, "arm,gic-v3");
75 	if (node < 0) {
76 		ERROR("SOCFPGA: Unable to locate node with arm,gic-v3 compatible property\n");
77 		return 0;
78 	}
79 	/* The GICv3 DT binding holds at least two address/size pairs,
80 	 * the first describing the distributor, the second the redistributors.
81 	 * See: bindings/interrupt-controller/arm,gic-v3.yaml
82 	 */
83 	err = fdt_get_reg_props_by_index(hw_config_dtb, node, 0, &addr, NULL);
84 	if (err < 0) {
85 		ERROR("SOCFPGA: Failed to read GICD reg property of GIC node\n");
86 	} else {
87 		plat_driver_data->gicd_base = addr;
88 	}
89 
90 	err = fdt_get_reg_props_by_index(hw_config_dtb, node, 1, &addr, NULL);
91 	if (err < 0) {
92 		ERROR("SOCFPGA: Failed to read GICR reg property of GIC node\n");
93 	} else {
94 		plat_driver_data->gicr_base = addr;
95 	}
96 	return err;
97 }
98 
99 int socfpga_dt_populate_dram_layout(uintptr_t dt_addr)
100 {
101 	int node;
102 	uintptr_t addr;
103 	size_t size;
104 
105 	/* Necessary to work with libfdt APIs */
106 	const void *hw_config_dtb = (const void *)dt_addr;
107 
108 	/* Find 'memory' node */
109 	node = fdt_node_offset_by_prop_value(hw_config_dtb, -1, "device_type",
110 					     "memory", sizeof("memory"));
111 	if (node < 0) {
112 		NOTICE("SOCFPGA: Unable to locate 'memory' node\n");
113 		return node;
114 	}
115 
116 	int err = fdt_get_reg_props_by_index(
117 			hw_config_dtb, node, 0,
118 			&addr, (size_t *)&size);
119 
120 	NOTICE("SOCFPGA: Mem base 0x%lx, Mem size 0x%lx\n", addr, size);
121 	if (err < 0) {
122 		ERROR("SOCFPGA: Failed to read 'reg' property of 'memory' node\n");
123 		return err;
124 	}
125 
126 	return 0;
127 }
128