xref: /rk3399_rockchip-uboot/arch/arm/mach-rockchip/param.c (revision b9bc76b4e104a91a212ea42d451dc52d237b5629)
1dbf8423eSJoseph Chen // SPDX-License-Identifier: GPL-2.0
2dbf8423eSJoseph Chen /*
3dbf8423eSJoseph Chen  * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
4dbf8423eSJoseph Chen  */
5dbf8423eSJoseph Chen 
6dbf8423eSJoseph Chen #include <common.h>
76e15146eSJoseph Chen #include <dm.h>
86e15146eSJoseph Chen #include <ram.h>
9dbf8423eSJoseph Chen #include <asm/io.h>
10dbf8423eSJoseph Chen #include <asm/arch/rk_atags.h>
11dbf8423eSJoseph Chen #include <asm/arch/param.h>
12dbf8423eSJoseph Chen 
13dbf8423eSJoseph Chen DECLARE_GLOBAL_DATA_PTR;
14dbf8423eSJoseph Chen 
15dbf8423eSJoseph Chen #define SDRAM_OFFSET(offset)		(CONFIG_SYS_SDRAM_BASE + (offset))
16dbf8423eSJoseph Chen #define PARAM_DRAM_INFO_OFFSET		(SZ_32M)
17dbf8423eSJoseph Chen #define PARAM_OPTEE_INFO_OFFSET		(SZ_32M + SZ_2M)
18dbf8423eSJoseph Chen 
19dbf8423eSJoseph Chen struct tos_param_t {
20dbf8423eSJoseph Chen 	u32 version;
21dbf8423eSJoseph Chen 	u32 checksum;
22dbf8423eSJoseph Chen 	struct {
23dbf8423eSJoseph Chen 		char name[8];
24dbf8423eSJoseph Chen 		s64 phy_addr;
25dbf8423eSJoseph Chen 		u32 size;
26dbf8423eSJoseph Chen 		u32 flags;
27dbf8423eSJoseph Chen 	} tee_mem;
28dbf8423eSJoseph Chen 	struct {
29dbf8423eSJoseph Chen 		char name[8];
30dbf8423eSJoseph Chen 		s64 phy_addr;
31dbf8423eSJoseph Chen 		u32 size;
32dbf8423eSJoseph Chen 		u32 flags;
33dbf8423eSJoseph Chen 	} drm_mem;
34dbf8423eSJoseph Chen 	s64 reserve[8];
35dbf8423eSJoseph Chen };
36dbf8423eSJoseph Chen 
37dbf8423eSJoseph Chen static uint16_t trust_checksum(const uint8_t *buf, uint16_t len)
38dbf8423eSJoseph Chen {
39dbf8423eSJoseph Chen 	uint16_t i, checksum = 0;
40dbf8423eSJoseph Chen 
41dbf8423eSJoseph Chen 	for (i = 0; i < len; i++) {
42dbf8423eSJoseph Chen 		if (i % 2)
43dbf8423eSJoseph Chen 			checksum += buf[i] << 8;
44dbf8423eSJoseph Chen 		else
45dbf8423eSJoseph Chen 			checksum += buf[i];
46dbf8423eSJoseph Chen 	}
47dbf8423eSJoseph Chen 	checksum = ~checksum;
48dbf8423eSJoseph Chen 
49dbf8423eSJoseph Chen 	return checksum;
50dbf8423eSJoseph Chen }
51dbf8423eSJoseph Chen 
526e15146eSJoseph Chen struct memblock param_parse_atf_mem(void)
53dbf8423eSJoseph Chen {
546e15146eSJoseph Chen 	struct memblock mem;
55dbf8423eSJoseph Chen 
566e15146eSJoseph Chen 	mem.base = 0;
576e15146eSJoseph Chen 	mem.size = 0;
58dbf8423eSJoseph Chen 
59dbf8423eSJoseph Chen #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
60dbf8423eSJoseph Chen 	struct tag *t = NULL;
61dbf8423eSJoseph Chen 
62dbf8423eSJoseph Chen 	/*
63dbf8423eSJoseph Chen 	 * Get memory region of ATF
64dbf8423eSJoseph Chen 	 *
65dbf8423eSJoseph Chen 	 * 1. New way: atags info;
66dbf8423eSJoseph Chen 	 * 2. Leagcy way: 2MB size and start from ddr 0x0 offset;
67dbf8423eSJoseph Chen 	 */
68dbf8423eSJoseph Chen 	t = atags_get_tag(ATAG_ATF_MEM);
69dbf8423eSJoseph Chen 	if (t && t->u.atf_mem.size) {
706e15146eSJoseph Chen 		mem.base = t->u.atf_mem.phy_addr;
716e15146eSJoseph Chen 		mem.size = t->u.atf_mem.size;
72dbf8423eSJoseph Chen 		/* Sanity */
736e15146eSJoseph Chen 		if (mem.base + mem.size > SDRAM_OFFSET(SZ_1M)) {
74dbf8423eSJoseph Chen 			printf("%s: ATF reserved region is not within 0-1MB "
75dbf8423eSJoseph Chen 			       "offset(0x%08llx-0x%08llx)!\n",
766e15146eSJoseph Chen 			       __func__, (u64)mem.base, (u64)mem.base + mem.size);
776e15146eSJoseph Chen 			return mem;
78dbf8423eSJoseph Chen 		}
79dbf8423eSJoseph Chen 	}
80dbf8423eSJoseph Chen #endif
81dbf8423eSJoseph Chen 
82dbf8423eSJoseph Chen 	/* Legacy */
836e15146eSJoseph Chen 	if (!mem.size) {
84dbf8423eSJoseph Chen 		if (IS_ENABLED(CONFIG_ARM64) ||
85dbf8423eSJoseph Chen 		    IS_ENABLED(CONFIG_ARM64_BOOT_AARCH32)) {
866e15146eSJoseph Chen 			mem.base = SDRAM_OFFSET(0);
876e15146eSJoseph Chen 			mem.size = SZ_1M;
88dbf8423eSJoseph Chen 		}
89dbf8423eSJoseph Chen 	}
90dbf8423eSJoseph Chen 
916e15146eSJoseph Chen 	debug("ATF: 0x%llx - 0x%llx\n", (u64)mem.base, (u64)mem.base + mem.size);
92dbf8423eSJoseph Chen 
936e15146eSJoseph Chen 	return mem;
94dbf8423eSJoseph Chen }
95dbf8423eSJoseph Chen 
966e15146eSJoseph Chen struct memblock param_parse_optee_mem(void)
97dbf8423eSJoseph Chen {
98dbf8423eSJoseph Chen 	struct tos_param_t *tos_parameter;
996e15146eSJoseph Chen 	struct memblock mem;
100dbf8423eSJoseph Chen 	u32 checksum;
101dbf8423eSJoseph Chen 
1026e15146eSJoseph Chen 	mem.base = 0;
1036e15146eSJoseph Chen 	mem.size = 0;
104dbf8423eSJoseph Chen 
105dbf8423eSJoseph Chen #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
106dbf8423eSJoseph Chen 	struct tag *t = NULL;
107dbf8423eSJoseph Chen 
108dbf8423eSJoseph Chen 	/*
109dbf8423eSJoseph Chen 	 * Get memory region of OP-TEE
110dbf8423eSJoseph Chen 	 *
111dbf8423eSJoseph Chen 	 * 1. New way: atags info;
112dbf8423eSJoseph Chen 	 * 2. Leagcy way: info in ddr 34M offset;
113dbf8423eSJoseph Chen 	 */
114dbf8423eSJoseph Chen 	t = atags_get_tag(ATAG_TOS_MEM);
115dbf8423eSJoseph Chen 	if (t && (t->u.tos_mem.tee_mem.flags == 1)) {
1166e15146eSJoseph Chen 		mem.base = t->u.tos_mem.tee_mem.phy_addr;
1176e15146eSJoseph Chen 		mem.size = t->u.tos_mem.tee_mem.size;
118dbf8423eSJoseph Chen 	}
119dbf8423eSJoseph Chen #endif
120dbf8423eSJoseph Chen 
121dbf8423eSJoseph Chen 	/* Legacy */
1226e15146eSJoseph Chen 	if (!mem.size) {
123dbf8423eSJoseph Chen 		tos_parameter =
124dbf8423eSJoseph Chen 		(struct tos_param_t *)(SDRAM_OFFSET(PARAM_OPTEE_INFO_OFFSET));
125dbf8423eSJoseph Chen 		checksum =
126dbf8423eSJoseph Chen 		trust_checksum((uint8_t *)(unsigned long)tos_parameter + 8,
127dbf8423eSJoseph Chen 			       sizeof(struct tos_param_t) - 8);
128dbf8423eSJoseph Chen 		if ((checksum == tos_parameter->checksum) &&
129dbf8423eSJoseph Chen 		    (tos_parameter->tee_mem.flags == 1)) {
1306e15146eSJoseph Chen 			mem.base = tos_parameter->tee_mem.phy_addr;
1316e15146eSJoseph Chen 			mem.size = tos_parameter->tee_mem.size;
13207ea4f34SJoseph Chen 		}
13307ea4f34SJoseph Chen 	}
13407ea4f34SJoseph Chen 
1356e15146eSJoseph Chen 	if (mem.size)
136dbf8423eSJoseph Chen 		gd->flags |= GD_FLG_BL32_ENABLED;
137dbf8423eSJoseph Chen 
1386e15146eSJoseph Chen 	debug("TOS: 0x%llx - 0x%llx\n", (u64)mem.base, (u64)mem.base + mem.size);
139dbf8423eSJoseph Chen 
1406e15146eSJoseph Chen 	return mem;
141dbf8423eSJoseph Chen }
142dbf8423eSJoseph Chen 
1436e15146eSJoseph Chen struct memblock param_parse_common_resv_mem(void)
144dbf8423eSJoseph Chen {
1456e15146eSJoseph Chen 	struct memblock mem;
146dbf8423eSJoseph Chen 
1476e15146eSJoseph Chen 	mem.base = SDRAM_OFFSET(SZ_1M);
1486e15146eSJoseph Chen 	mem.size = SZ_1M;
149dbf8423eSJoseph Chen 
1506e15146eSJoseph Chen 	return mem;
151dbf8423eSJoseph Chen }
152dbf8423eSJoseph Chen 
153dbf8423eSJoseph Chen int param_parse_bootdev(char **devtype, char **devnum)
154dbf8423eSJoseph Chen {
155dbf8423eSJoseph Chen #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
156dbf8423eSJoseph Chen 	struct tag *t;
157dbf8423eSJoseph Chen 
158dbf8423eSJoseph Chen 	t = atags_get_tag(ATAG_BOOTDEV);
159dbf8423eSJoseph Chen 	if (t) {
160dbf8423eSJoseph Chen 		switch (t->u.bootdev.devtype) {
161dbf8423eSJoseph Chen 		case BOOT_TYPE_EMMC:
162dbf8423eSJoseph Chen 			*devtype = "mmc";
163dbf8423eSJoseph Chen 			*devnum = "0";
164dbf8423eSJoseph Chen 			break;
165dbf8423eSJoseph Chen 		case BOOT_TYPE_SD0:
166dbf8423eSJoseph Chen 		case BOOT_TYPE_SD1:
167dbf8423eSJoseph Chen 			*devtype = "mmc";
168dbf8423eSJoseph Chen 			*devnum = "1";
169dbf8423eSJoseph Chen 			break;
170dbf8423eSJoseph Chen 		case BOOT_TYPE_NAND:
171dbf8423eSJoseph Chen 			*devtype = "rknand";
172dbf8423eSJoseph Chen 			*devnum = "0";
173dbf8423eSJoseph Chen 			break;
174dbf8423eSJoseph Chen 		case BOOT_TYPE_SPI_NAND:
175dbf8423eSJoseph Chen 			*devtype = "spinand";
176dbf8423eSJoseph Chen 			*devnum = "0";
177dbf8423eSJoseph Chen 			break;
178dbf8423eSJoseph Chen 		case BOOT_TYPE_SPI_NOR:
179dbf8423eSJoseph Chen 			*devtype = "spinor";
180dbf8423eSJoseph Chen 			*devnum = "1";
181dbf8423eSJoseph Chen 			break;
182dbf8423eSJoseph Chen 		case BOOT_TYPE_RAM:
183dbf8423eSJoseph Chen 			*devtype = "ramdisk";
184dbf8423eSJoseph Chen 			*devnum = "0";
185dbf8423eSJoseph Chen 			break;
186dbf8423eSJoseph Chen 		default:
187dbf8423eSJoseph Chen 			printf("Unknown bootdev type: 0x%x\n",
188dbf8423eSJoseph Chen 			       t->u.bootdev.devtype);
189dbf8423eSJoseph Chen 			return -EINVAL;
190dbf8423eSJoseph Chen 		}
191dbf8423eSJoseph Chen 
192dbf8423eSJoseph Chen 		return 0;
193dbf8423eSJoseph Chen 	}
194dbf8423eSJoseph Chen #endif
195dbf8423eSJoseph Chen 
196dbf8423eSJoseph Chen 	return -ENOSYS;
197dbf8423eSJoseph Chen }
198*b9bc76b4SJoseph Chen 
199*b9bc76b4SJoseph Chen struct memblock *param_parse_ddr_mem(int *out_count)
200*b9bc76b4SJoseph Chen {
201*b9bc76b4SJoseph Chen 	struct udevice *dev;
202*b9bc76b4SJoseph Chen 	struct memblock *mem;
203*b9bc76b4SJoseph Chen 	struct ram_info ram;
204*b9bc76b4SJoseph Chen 	int i, ret, count;
205*b9bc76b4SJoseph Chen 
206*b9bc76b4SJoseph Chen 	/*
207*b9bc76b4SJoseph Chen 	 * Get memory region of DDR
208*b9bc76b4SJoseph Chen 	 *
209*b9bc76b4SJoseph Chen 	 * 1. New: atags info;
210*b9bc76b4SJoseph Chen 	 * 2. Leagcy: os register;
211*b9bc76b4SJoseph Chen 	 */
212*b9bc76b4SJoseph Chen #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
213*b9bc76b4SJoseph Chen 	struct tag *t;
214*b9bc76b4SJoseph Chen 
215*b9bc76b4SJoseph Chen 	t = atags_get_tag(ATAG_DDR_MEM);
216*b9bc76b4SJoseph Chen 	if (t && t->u.ddr_mem.count) {
217*b9bc76b4SJoseph Chen 		count = t->u.ddr_mem.count;
218*b9bc76b4SJoseph Chen 		mem = calloc(count, sizeof(*mem));
219*b9bc76b4SJoseph Chen 		if (!mem) {
220*b9bc76b4SJoseph Chen 			printf("Calloc ddr memory failed\n");
221*b9bc76b4SJoseph Chen 			return 0;
222*b9bc76b4SJoseph Chen 		}
223*b9bc76b4SJoseph Chen 
224*b9bc76b4SJoseph Chen 		for (i = 0; i < count; i++) {
225*b9bc76b4SJoseph Chen 			mem[i].base = t->u.ddr_mem.bank[i];
226*b9bc76b4SJoseph Chen 			mem[i].size = t->u.ddr_mem.bank[i + count];
227*b9bc76b4SJoseph Chen 		}
228*b9bc76b4SJoseph Chen 
229*b9bc76b4SJoseph Chen 		*out_count = count;
230*b9bc76b4SJoseph Chen 		return mem;
231*b9bc76b4SJoseph Chen 	}
232*b9bc76b4SJoseph Chen #endif
233*b9bc76b4SJoseph Chen 
234*b9bc76b4SJoseph Chen 	/* Leagcy */
235*b9bc76b4SJoseph Chen 	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
236*b9bc76b4SJoseph Chen 	if (ret) {
237*b9bc76b4SJoseph Chen 		debug("DRAM init failed: %d\n", ret);
238*b9bc76b4SJoseph Chen 		return NULL;
239*b9bc76b4SJoseph Chen 	}
240*b9bc76b4SJoseph Chen 	ret = ram_get_info(dev, &ram);
241*b9bc76b4SJoseph Chen 	if (ret) {
242*b9bc76b4SJoseph Chen 		debug("Cannot get DRAM size: %d\n", ret);
243*b9bc76b4SJoseph Chen 		return NULL;
244*b9bc76b4SJoseph Chen 	}
245*b9bc76b4SJoseph Chen 
246*b9bc76b4SJoseph Chen 	debug("SDRAM base=%lx, size=%lx\n",
247*b9bc76b4SJoseph Chen 	      (unsigned long)ram.base, (unsigned long)ram.size);
248*b9bc76b4SJoseph Chen 
249*b9bc76b4SJoseph Chen 	count = 1;
250*b9bc76b4SJoseph Chen 	mem = calloc(1, sizeof(*mem));
251*b9bc76b4SJoseph Chen 	if (!mem) {
252*b9bc76b4SJoseph Chen 		printf("Calloc ddr memory failed\n");
253*b9bc76b4SJoseph Chen 		return 0;
254*b9bc76b4SJoseph Chen 	}
255*b9bc76b4SJoseph Chen 
256*b9bc76b4SJoseph Chen 	for (i = 0; i < count; i++) {
257*b9bc76b4SJoseph Chen 		mem[i].base = CONFIG_SYS_SDRAM_BASE;
258*b9bc76b4SJoseph Chen 		mem[i].size = ram.size;
259*b9bc76b4SJoseph Chen 	}
260*b9bc76b4SJoseph Chen 
261*b9bc76b4SJoseph Chen 	*out_count = count;
262*b9bc76b4SJoseph Chen 	return mem;
263*b9bc76b4SJoseph Chen }
264