xref: /rk3399_rockchip-uboot/arch/arm/mach-rockchip/param.c (revision 9cde1b1d0397a62bc2c5c1bbee2f9f7a41208b8f)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
4  */
5 
6 #include <common.h>
7 #include <dm.h>
8 #include <ram.h>
9 #include <asm/io.h>
10 #include <asm/arch/rk_atags.h>
11 #include <asm/arch/param.h>
12 
13 DECLARE_GLOBAL_DATA_PTR;
14 
15 #define SZ_4GB				0x100000000ULL
16 
17 #if !defined(CONFIG_SPL_BUILD) && !defined(CONFIG_TPL_BUILD)
18 #define SDRAM_OFFSET(offset)		(CONFIG_SYS_SDRAM_BASE + (offset))
19 #define PARAM_DRAM_INFO_OFFSET		(SZ_32M)
20 #define PARAM_OPTEE_INFO_OFFSET		(SZ_32M + SZ_2M)
21 
22 struct tos_param_t {
23 	u32 version;
24 	u32 checksum;
25 	struct {
26 		char name[8];
27 		s64 phy_addr;
28 		u32 size;
29 		u32 flags;
30 	} tee_mem;
31 	struct {
32 		char name[8];
33 		s64 phy_addr;
34 		u32 size;
35 		u32 flags;
36 	} drm_mem;
37 	s64 reserve[8];
38 };
39 
40 static uint16_t trust_checksum(const uint8_t *buf, uint16_t len)
41 {
42 	uint16_t i, checksum = 0;
43 
44 	for (i = 0; i < len; i++) {
45 		if (i % 2)
46 			checksum += buf[i] << 8;
47 		else
48 			checksum += buf[i];
49 	}
50 	checksum = ~checksum;
51 
52 	return checksum;
53 }
54 
55 struct memblock param_parse_atf_mem(void)
56 {
57 	struct memblock mem;
58 
59 	mem.base = 0;
60 	mem.size = 0;
61 
62 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
63 	struct tag *t = NULL;
64 
65 	/*
66 	 * Get memory region of ATF
67 	 *
68 	 * 1. New way: atags info;
69 	 * 2. Leagcy way: 2MB size and start from ddr 0x0 offset;
70 	 */
71 	t = atags_get_tag(ATAG_ATF_MEM);
72 	if (t && t->u.atf_mem.size) {
73 		mem.base = t->u.atf_mem.phy_addr;
74 		mem.size = t->u.atf_mem.size;
75 		/* Sanity */
76 		if (mem.base + mem.size > SDRAM_OFFSET(SZ_1M)) {
77 			printf("%s: ATF reserved region is not within 0-1MB "
78 			       "offset(0x%08llx-0x%08llx)!\n",
79 			       __func__, (u64)mem.base, (u64)mem.base + mem.size);
80 			return mem;
81 		}
82 	}
83 #endif
84 
85 	/* Legacy */
86 	if (!mem.size) {
87 		if (IS_ENABLED(CONFIG_ARM64) ||
88 		    IS_ENABLED(CONFIG_ARM64_BOOT_AARCH32)) {
89 			mem.base = SDRAM_OFFSET(0);
90 			mem.size = SZ_1M;
91 		}
92 	}
93 
94 	debug("ATF: 0x%llx - 0x%llx\n", (u64)mem.base, (u64)mem.base + mem.size);
95 
96 	return mem;
97 }
98 
99 struct memblock param_parse_optee_mem(void)
100 {
101 	struct tos_param_t *tos_parameter;
102 	struct memblock mem;
103 	u32 checksum;
104 
105 	mem.base = 0;
106 	mem.size = 0;
107 
108 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
109 	struct tag *t = NULL;
110 
111 	/*
112 	 * Get memory region of OP-TEE
113 	 *
114 	 * 1. New way: atags info;
115 	 * 2. Leagcy way: info in ddr 34M offset;
116 	 */
117 	t = atags_get_tag(ATAG_TOS_MEM);
118 	if (t && (t->u.tos_mem.tee_mem.flags == 1)) {
119 		mem.base = t->u.tos_mem.tee_mem.phy_addr;
120 		mem.size = t->u.tos_mem.tee_mem.size;
121 	}
122 #endif
123 
124 	/* Legacy */
125 	if (!mem.size) {
126 		tos_parameter =
127 		(struct tos_param_t *)(SDRAM_OFFSET(PARAM_OPTEE_INFO_OFFSET));
128 		checksum =
129 		trust_checksum((uint8_t *)(unsigned long)tos_parameter + 8,
130 			       sizeof(struct tos_param_t) - 8);
131 		if ((checksum == tos_parameter->checksum) &&
132 		    (tos_parameter->tee_mem.flags == 1)) {
133 			mem.base = tos_parameter->tee_mem.phy_addr;
134 			mem.size = tos_parameter->tee_mem.size;
135 		}
136 	}
137 
138 	if (mem.size)
139 		gd->flags |= GD_FLG_BL32_ENABLED;
140 
141 	debug("TOS: 0x%llx - 0x%llx\n", (u64)mem.base, (u64)mem.base + mem.size);
142 
143 	return mem;
144 }
145 
146 struct memblock param_parse_common_resv_mem(void)
147 {
148 	struct memblock mem;
149 
150 #if defined(CONFIG_ARM64)
151 	mem.base = SDRAM_OFFSET(SZ_1M);
152 	mem.size = SZ_1M;
153 /*
154  * The ARMv8 platform enabling AArch32 mode should reserve memory the same
155  * as AArch64 mode(because there is no difference about ATF), only some
156  * platform has special request, they are: RK3308.
157  */
158 #elif defined(CONFIG_ARM64_BOOT_AARCH32) && !defined(CONFIG_ROCKCHIP_RK3308)
159 	mem.base = SDRAM_OFFSET(SZ_1M);
160 	mem.size = SZ_1M;
161 #else
162 	mem.size = 0;
163 #endif
164 	return mem;
165 }
166 
167 int param_parse_bootdev(char **devtype, char **devnum)
168 {
169 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
170 	struct tag *t;
171 
172 	t = atags_get_tag(ATAG_BOOTDEV);
173 	if (t) {
174 		switch (t->u.bootdev.devtype) {
175 #ifdef CONFIG_DM_MMC
176 		case BOOT_TYPE_EMMC:
177 			*devtype = "mmc";
178 			*devnum = "0";
179 			break;
180 		case BOOT_TYPE_SD0:
181 		case BOOT_TYPE_SD1:
182 			*devtype = "mmc";
183 			*devnum = "1";
184 			/*
185 			 * If preloader does not pass sdupdate value, we treat it
186 			 * as a unknown card and call the rkimgtest cmd to find
187 			 * out what it is.
188 			 *
189 			 * If preloader pass sdupdate value as an update card,
190 			 * we just set "sdfwupdate" to bootargs instead of
191 			 * calling rkimgtest cmd which consumes time.
192 			 */
193 			if (t->u.bootdev.sdupdate == SD_UNKNOWN_CARD) {
194 				run_command("mmc dev 1", 0);
195 				run_command("rkimgtest mmc 1", 0);
196 			} else if (t->u.bootdev.sdupdate == SD_UPDATE_CARD) {
197 				env_update("bootargs", "sdfwupdate");
198 			}
199 			break;
200 #endif
201 #if defined(CONFIG_RKNAND) || defined(CONFIG_RKNANDC_NAND)
202 		case BOOT_TYPE_NAND:
203 			*devtype = "rknand";
204 			*devnum = "0";
205 			break;
206 #endif
207 #ifdef CONFIG_RKSFC_NAND
208 		case BOOT_TYPE_SPI_NAND:
209 			*devtype = "spinand";
210 			*devnum = "0";
211 			break;
212 #endif
213 #ifdef CONFIG_RKSFC_NOR
214 		case BOOT_TYPE_SPI_NOR:
215 			*devtype = "spinor";
216 			*devnum = "1";
217 			break;
218 #endif
219 #ifdef CONFIG_DM_RAMDISK
220 		case BOOT_TYPE_RAM:
221 			*devtype = "ramdisk";
222 			*devnum = "0";
223 			break;
224 #endif
225 		default:
226 			printf("Unknown bootdev type: 0x%x\n",
227 			       t->u.bootdev.devtype);
228 			return -EINVAL;
229 		}
230 
231 		return 0;
232 	}
233 #endif
234 
235 	return -ENOSYS;
236 }
237 #endif
238 
239 static phys_size_t ddr_mem_get_usable_size(u64 base, u64 size)
240 {
241 	return (base + size >= CONFIG_SYS_SDRAM_BASE + SDRAM_MAX_SIZE) ?
242 	       (CONFIG_SYS_SDRAM_BASE + SDRAM_MAX_SIZE - base) : size;
243 }
244 
245 struct memblock *param_parse_ddr_mem(int *out_count)
246 {
247 	struct udevice *dev;
248 	struct memblock *mem;
249 	struct ram_info ram;
250 	int i, ret, count;
251 
252 	/*
253 	 * Get memory region of DDR
254 	 *
255 	 * 1. New: atags info;
256 	 * 2. Leagcy: os register;
257 	 */
258 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
259 	struct tag *t;
260 	u64 base, size;
261 	int n;
262 
263 	t = atags_get_tag(ATAG_DDR_MEM);
264 	if (t && t->u.ddr_mem.count) {
265 		count = t->u.ddr_mem.count;
266 		mem = calloc(count + MEM_RESV_COUNT, sizeof(*mem));
267 		if (!mem) {
268 			printf("Calloc ddr memory failed\n");
269 			return 0;
270 		}
271 
272 		for (i = 0, n = 0; i < count; i++, n++) {
273 			base = t->u.ddr_mem.bank[i];
274 			size = t->u.ddr_mem.bank[i + count];
275 
276 			/* 0~4GB */
277 			if (base < SZ_4GB) {
278 				mem[n].base = base;
279 				mem[n].size = ddr_mem_get_usable_size(base, size);
280 				if (base + size > SZ_4GB) {
281 					n++;
282 					mem[n].base_u64 = SZ_4GB;
283 					mem[n].size_u64 = base + size - SZ_4GB;
284 				}
285 			} else {
286 				/* 4GB+ */
287 				mem[n].base_u64 = base;
288 				mem[n].size_u64 = size;
289 			}
290 
291 			assert(n < count + MEM_RESV_COUNT);
292 		}
293 
294 		*out_count = n;
295 		return mem;
296 	}
297 #endif
298 
299 	/* Leagcy */
300 	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
301 	if (ret) {
302 		debug("DRAM init failed: %d\n", ret);
303 		return NULL;
304 	}
305 	ret = ram_get_info(dev, &ram);
306 	if (ret) {
307 		debug("Cannot get DRAM size: %d\n", ret);
308 		return NULL;
309 	}
310 
311 	debug("SDRAM base=%lx, size=%lx\n",
312 	      (unsigned long)ram.base, (unsigned long)ram.size);
313 
314 	count = 1;
315 	mem = calloc(1, sizeof(*mem));
316 	if (!mem) {
317 		printf("Calloc ddr memory failed\n");
318 		return 0;
319 	}
320 
321 	for (i = 0; i < count; i++) {
322 		mem[i].base = CONFIG_SYS_SDRAM_BASE;
323 		mem[i].size = ddr_mem_get_usable_size(mem[i].base, ram.size);
324 	}
325 
326 	*out_count = count;
327 	return mem;
328 }
329