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