xref: /rk3399_rockchip-uboot/arch/arm/mach-rockchip/param.c (revision b9bc76b4e104a91a212ea42d451dc52d237b5629)
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 SDRAM_OFFSET(offset)		(CONFIG_SYS_SDRAM_BASE + (offset))
16 #define PARAM_DRAM_INFO_OFFSET		(SZ_32M)
17 #define PARAM_OPTEE_INFO_OFFSET		(SZ_32M + SZ_2M)
18 
19 struct tos_param_t {
20 	u32 version;
21 	u32 checksum;
22 	struct {
23 		char name[8];
24 		s64 phy_addr;
25 		u32 size;
26 		u32 flags;
27 	} tee_mem;
28 	struct {
29 		char name[8];
30 		s64 phy_addr;
31 		u32 size;
32 		u32 flags;
33 	} drm_mem;
34 	s64 reserve[8];
35 };
36 
37 static uint16_t trust_checksum(const uint8_t *buf, uint16_t len)
38 {
39 	uint16_t i, checksum = 0;
40 
41 	for (i = 0; i < len; i++) {
42 		if (i % 2)
43 			checksum += buf[i] << 8;
44 		else
45 			checksum += buf[i];
46 	}
47 	checksum = ~checksum;
48 
49 	return checksum;
50 }
51 
52 struct memblock param_parse_atf_mem(void)
53 {
54 	struct memblock mem;
55 
56 	mem.base = 0;
57 	mem.size = 0;
58 
59 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
60 	struct tag *t = NULL;
61 
62 	/*
63 	 * Get memory region of ATF
64 	 *
65 	 * 1. New way: atags info;
66 	 * 2. Leagcy way: 2MB size and start from ddr 0x0 offset;
67 	 */
68 	t = atags_get_tag(ATAG_ATF_MEM);
69 	if (t && t->u.atf_mem.size) {
70 		mem.base = t->u.atf_mem.phy_addr;
71 		mem.size = t->u.atf_mem.size;
72 		/* Sanity */
73 		if (mem.base + mem.size > SDRAM_OFFSET(SZ_1M)) {
74 			printf("%s: ATF reserved region is not within 0-1MB "
75 			       "offset(0x%08llx-0x%08llx)!\n",
76 			       __func__, (u64)mem.base, (u64)mem.base + mem.size);
77 			return mem;
78 		}
79 	}
80 #endif
81 
82 	/* Legacy */
83 	if (!mem.size) {
84 		if (IS_ENABLED(CONFIG_ARM64) ||
85 		    IS_ENABLED(CONFIG_ARM64_BOOT_AARCH32)) {
86 			mem.base = SDRAM_OFFSET(0);
87 			mem.size = SZ_1M;
88 		}
89 	}
90 
91 	debug("ATF: 0x%llx - 0x%llx\n", (u64)mem.base, (u64)mem.base + mem.size);
92 
93 	return mem;
94 }
95 
96 struct memblock param_parse_optee_mem(void)
97 {
98 	struct tos_param_t *tos_parameter;
99 	struct memblock mem;
100 	u32 checksum;
101 
102 	mem.base = 0;
103 	mem.size = 0;
104 
105 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
106 	struct tag *t = NULL;
107 
108 	/*
109 	 * Get memory region of OP-TEE
110 	 *
111 	 * 1. New way: atags info;
112 	 * 2. Leagcy way: info in ddr 34M offset;
113 	 */
114 	t = atags_get_tag(ATAG_TOS_MEM);
115 	if (t && (t->u.tos_mem.tee_mem.flags == 1)) {
116 		mem.base = t->u.tos_mem.tee_mem.phy_addr;
117 		mem.size = t->u.tos_mem.tee_mem.size;
118 	}
119 #endif
120 
121 	/* Legacy */
122 	if (!mem.size) {
123 		tos_parameter =
124 		(struct tos_param_t *)(SDRAM_OFFSET(PARAM_OPTEE_INFO_OFFSET));
125 		checksum =
126 		trust_checksum((uint8_t *)(unsigned long)tos_parameter + 8,
127 			       sizeof(struct tos_param_t) - 8);
128 		if ((checksum == tos_parameter->checksum) &&
129 		    (tos_parameter->tee_mem.flags == 1)) {
130 			mem.base = tos_parameter->tee_mem.phy_addr;
131 			mem.size = tos_parameter->tee_mem.size;
132 		}
133 	}
134 
135 	if (mem.size)
136 		gd->flags |= GD_FLG_BL32_ENABLED;
137 
138 	debug("TOS: 0x%llx - 0x%llx\n", (u64)mem.base, (u64)mem.base + mem.size);
139 
140 	return mem;
141 }
142 
143 struct memblock param_parse_common_resv_mem(void)
144 {
145 	struct memblock mem;
146 
147 	mem.base = SDRAM_OFFSET(SZ_1M);
148 	mem.size = SZ_1M;
149 
150 	return mem;
151 }
152 
153 int param_parse_bootdev(char **devtype, char **devnum)
154 {
155 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
156 	struct tag *t;
157 
158 	t = atags_get_tag(ATAG_BOOTDEV);
159 	if (t) {
160 		switch (t->u.bootdev.devtype) {
161 		case BOOT_TYPE_EMMC:
162 			*devtype = "mmc";
163 			*devnum = "0";
164 			break;
165 		case BOOT_TYPE_SD0:
166 		case BOOT_TYPE_SD1:
167 			*devtype = "mmc";
168 			*devnum = "1";
169 			break;
170 		case BOOT_TYPE_NAND:
171 			*devtype = "rknand";
172 			*devnum = "0";
173 			break;
174 		case BOOT_TYPE_SPI_NAND:
175 			*devtype = "spinand";
176 			*devnum = "0";
177 			break;
178 		case BOOT_TYPE_SPI_NOR:
179 			*devtype = "spinor";
180 			*devnum = "1";
181 			break;
182 		case BOOT_TYPE_RAM:
183 			*devtype = "ramdisk";
184 			*devnum = "0";
185 			break;
186 		default:
187 			printf("Unknown bootdev type: 0x%x\n",
188 			       t->u.bootdev.devtype);
189 			return -EINVAL;
190 		}
191 
192 		return 0;
193 	}
194 #endif
195 
196 	return -ENOSYS;
197 }
198 
199 struct memblock *param_parse_ddr_mem(int *out_count)
200 {
201 	struct udevice *dev;
202 	struct memblock *mem;
203 	struct ram_info ram;
204 	int i, ret, count;
205 
206 	/*
207 	 * Get memory region of DDR
208 	 *
209 	 * 1. New: atags info;
210 	 * 2. Leagcy: os register;
211 	 */
212 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
213 	struct tag *t;
214 
215 	t = atags_get_tag(ATAG_DDR_MEM);
216 	if (t && t->u.ddr_mem.count) {
217 		count = t->u.ddr_mem.count;
218 		mem = calloc(count, sizeof(*mem));
219 		if (!mem) {
220 			printf("Calloc ddr memory failed\n");
221 			return 0;
222 		}
223 
224 		for (i = 0; i < count; i++) {
225 			mem[i].base = t->u.ddr_mem.bank[i];
226 			mem[i].size = t->u.ddr_mem.bank[i + count];
227 		}
228 
229 		*out_count = count;
230 		return mem;
231 	}
232 #endif
233 
234 	/* Leagcy */
235 	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
236 	if (ret) {
237 		debug("DRAM init failed: %d\n", ret);
238 		return NULL;
239 	}
240 	ret = ram_get_info(dev, &ram);
241 	if (ret) {
242 		debug("Cannot get DRAM size: %d\n", ret);
243 		return NULL;
244 	}
245 
246 	debug("SDRAM base=%lx, size=%lx\n",
247 	      (unsigned long)ram.base, (unsigned long)ram.size);
248 
249 	count = 1;
250 	mem = calloc(1, sizeof(*mem));
251 	if (!mem) {
252 		printf("Calloc ddr memory failed\n");
253 		return 0;
254 	}
255 
256 	for (i = 0; i < count; i++) {
257 		mem[i].base = CONFIG_SYS_SDRAM_BASE;
258 		mem[i].size = ram.size;
259 	}
260 
261 	*out_count = count;
262 	return mem;
263 }
264