xref: /rk3399_ARM-atf/plat/arm/board/morello/morello_image_load.c (revision 10fd85d8f4a8f338942616ed403a1e02a388a16f)
1 /*
2  * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <arch_helpers.h>
8 #include <common/debug.h>
9 #include <common/desc_image_load.h>
10 #include <drivers/arm/css/sds.h>
11 #include <libfdt.h>
12 
13 #include "morello_def.h"
14 #include <plat/arm/common/plat_arm.h>
15 #include <plat/common/platform.h>
16 
17 /* In client mode, a part of the DDR memory is reserved for Tag bits.
18  * Calculate the usable memory size after subtracting the Tag memory.
19  */
20 static inline uint64_t get_mem_client_mode(uint64_t size)
21 {
22 	return (size - (size / 128ULL));
23 }
24 
25 /*******************************************************************************
26  * This function inserts Platform information and firmware versions
27  * via device tree nodes as,
28  *	platform-info {
29  *		local-ddr-size = <0x0 0x0>;
30  *#ifdef TARGET_PLATFORM_SOC
31  *		remote-ddr-size = <0x0 0x0>;
32  *		remote-chip-count = <0x0>;
33  *		multichip-mode = <0x0>;
34  *		scc-config = <0x0>;
35  *#endif
36  *	};
37  *	firmware-version {
38  *#ifdef TARGET_PLATFORM_SOC
39  *		mcc-fw-version = <0x0>;
40  *		pcc-fw-version = <0x0>;
41  *#endif
42  *		scp-fw-version = <0x0>;
43  *		scp-fw-commit = <0x0>;
44  *	};
45  ******************************************************************************/
46 static int plat_morello_append_config_node(struct morello_plat_info *plat_info,
47 				struct morello_firmware_version *fw_version)
48 {
49 	bl_mem_params_node_t *mem_params;
50 	void *fdt;
51 	int nodeoffset_plat, nodeoffset_fw, err;
52 	uint64_t usable_mem_size;
53 
54 	usable_mem_size = plat_info->local_ddr_size;
55 
56 	mem_params = get_bl_mem_params_node(NT_FW_CONFIG_ID);
57 	if (mem_params == NULL) {
58 		ERROR("NT_FW CONFIG base address is NULL\n");
59 		return -1;
60 	}
61 
62 	fdt = (void *)(mem_params->image_info.image_base);
63 
64 	/* Check the validity of the fdt */
65 	if (fdt_check_header(fdt) != 0) {
66 		ERROR("Invalid NT_FW_CONFIG DTB passed\n");
67 		return -1;
68 	}
69 
70 	nodeoffset_plat = fdt_subnode_offset(fdt, 0, "platform-info");
71 	if (nodeoffset_plat < 0) {
72 		ERROR("NT_FW_CONFIG: Failed to get platform-info node offset\n");
73 		return -1;
74 	}
75 
76 	nodeoffset_fw = fdt_subnode_offset(fdt, 0, "firmware-version");
77 	if (nodeoffset_fw < 0) {
78 		ERROR("NT_FW_CONFIG: Failed to get firmware-version node offset\n");
79 		return -1;
80 	}
81 
82 #ifdef TARGET_PLATFORM_SOC
83 	err = fdt_setprop_u64(fdt, nodeoffset_plat, "remote-ddr-size",
84 			plat_info->remote_ddr_size);
85 	if (err < 0) {
86 		ERROR("NT_FW_CONFIG: Failed to set remote-ddr-size\n");
87 		return -1;
88 	}
89 
90 	err = fdt_setprop_u32(fdt, nodeoffset_plat, "remote-chip-count",
91 			plat_info->remote_chip_count);
92 	if (err < 0) {
93 		ERROR("NT_FW_CONFIG: Failed to set remote-chip-count\n");
94 		return -1;
95 	}
96 
97 	err = fdt_setprop_u32(fdt, nodeoffset_plat, "multichip-mode",
98 			plat_info->multichip_mode);
99 	if (err < 0) {
100 		ERROR("NT_FW_CONFIG: Failed to set multichip-mode\n");
101 		return -1;
102 	}
103 
104 	err = fdt_setprop_u32(fdt, nodeoffset_plat, "scc-config",
105 			plat_info->scc_config);
106 	if (err < 0) {
107 		ERROR("NT_FW_CONFIG: Failed to set scc-config\n");
108 		return -1;
109 	}
110 
111 	if (plat_info->scc_config & MORELLO_SCC_CLIENT_MODE_MASK) {
112 		usable_mem_size = get_mem_client_mode(plat_info->local_ddr_size);
113 	}
114 
115 	err = fdt_setprop_u32(fdt, nodeoffset_fw, "mcc-fw-version",
116 			fw_version->mcc_fw_ver);
117 	if (err < 0) {
118 		ERROR("NT_FW_CONFIG: Failed to set mcc-fw-version\n");
119 		return -1;
120 	}
121 
122 	err = fdt_setprop_u32(fdt, nodeoffset_fw, "pcc-fw-version",
123 			fw_version->pcc_fw_ver);
124 	if (err < 0) {
125 		ERROR("NT_FW_CONFIG: Failed to set pcc-fw-version\n");
126 		return -1;
127 	}
128 #endif
129 	err = fdt_setprop_u32(fdt, nodeoffset_fw, "scp-fw-version",
130 			fw_version->scp_fw_ver);
131 	if (err < 0) {
132 		ERROR("NT_FW_CONFIG: Failed to set scp-fw-version\n");
133 		return -1;
134 	}
135 
136 	err = fdt_setprop_u32(fdt, nodeoffset_fw, "scp-fw-commit",
137 			fw_version->scp_fw_commit);
138 	if (err < 0) {
139 		ERROR("NT_FW_CONFIG: Failed to set scp-fw-commit\n");
140 		return -1;
141 	}
142 
143 	err = fdt_setprop_u64(fdt, nodeoffset_plat, "local-ddr-size",
144 			usable_mem_size);
145 	if (err < 0) {
146 		ERROR("NT_FW_CONFIG: Failed to set local-ddr-size\n");
147 		return -1;
148 	}
149 
150 	flush_dcache_range((uintptr_t)fdt, mem_params->image_info.image_size);
151 
152 	return 0;
153 }
154 
155 /*******************************************************************************
156  * This function returns the list of executable images.
157  ******************************************************************************/
158 bl_params_t *plat_get_next_bl_params(void)
159 {
160 	int ret;
161 	struct morello_plat_info plat_info;
162 	struct morello_firmware_version fw_version;
163 
164 	ret = sds_init();
165 	if (ret != SDS_OK) {
166 		ERROR("SDS initialization failed. ret:%d\n", ret);
167 		panic();
168 	}
169 
170 	ret = sds_struct_read(MORELLO_SDS_PLATFORM_INFO_STRUCT_ID,
171 				MORELLO_SDS_PLATFORM_INFO_OFFSET,
172 				&plat_info,
173 				MORELLO_SDS_PLATFORM_INFO_SIZE,
174 				SDS_ACCESS_MODE_NON_CACHED);
175 	if (ret != SDS_OK) {
176 		ERROR("Error getting platform info from SDS. ret:%d\n", ret);
177 		panic();
178 	}
179 
180 	ret = sds_struct_read(MORELLO_SDS_FIRMWARE_VERSION_STRUCT_ID,
181 				MORELLO_SDS_FIRMWARE_VERSION_OFFSET,
182 				&fw_version,
183 				MORELLO_SDS_FIRMWARE_VERSION_SIZE,
184 				SDS_ACCESS_MODE_NON_CACHED);
185 	if (ret != SDS_OK) {
186 		ERROR("Error getting firmware version from SDS. ret:%d\n", ret);
187 		panic();
188 	}
189 
190 	/* Validate plat_info SDS */
191 #ifdef TARGET_PLATFORM_FVP
192 	if (plat_info.local_ddr_size == 0U) {
193 #else
194 	if ((plat_info.local_ddr_size == 0U)
195 		|| (plat_info.local_ddr_size > MORELLO_MAX_DDR_CAPACITY)
196 		|| (plat_info.remote_ddr_size > MORELLO_MAX_DDR_CAPACITY)
197 		|| (plat_info.remote_chip_count > MORELLO_MAX_REMOTE_CHIP_COUNT)
198 		){
199 #endif
200 		ERROR("platform info SDS is corrupted\n");
201 		panic();
202 	}
203 
204 	ret = plat_morello_append_config_node(&plat_info, &fw_version);
205 	if (ret != 0) {
206 		panic();
207 	}
208 
209 	return arm_get_next_bl_params();
210 }
211