xref: /rk3399_rockchip-uboot/arch/arm/mach-rockchip/param.c (revision d8e6f8d04d4bb33784339ba7ab1881ac7f1d2e2d)
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 
150453d738SJoseph Chen #define SZ_4GB				0x100000000ULL
160453d738SJoseph Chen 
177a00e4e5SJoseph Chen #ifndef CONFIG_SPL_BUILD
18dbf8423eSJoseph Chen #define SDRAM_OFFSET(offset)		(CONFIG_SYS_SDRAM_BASE + (offset))
19dbf8423eSJoseph Chen #define PARAM_DRAM_INFO_OFFSET		(SZ_32M)
20dbf8423eSJoseph Chen #define PARAM_OPTEE_INFO_OFFSET		(SZ_32M + SZ_2M)
21dbf8423eSJoseph Chen 
22dbf8423eSJoseph Chen struct tos_param_t {
23dbf8423eSJoseph Chen 	u32 version;
24dbf8423eSJoseph Chen 	u32 checksum;
25dbf8423eSJoseph Chen 	struct {
26dbf8423eSJoseph Chen 		char name[8];
27dbf8423eSJoseph Chen 		s64 phy_addr;
28dbf8423eSJoseph Chen 		u32 size;
29dbf8423eSJoseph Chen 		u32 flags;
30dbf8423eSJoseph Chen 	} tee_mem;
31dbf8423eSJoseph Chen 	struct {
32dbf8423eSJoseph Chen 		char name[8];
33dbf8423eSJoseph Chen 		s64 phy_addr;
34dbf8423eSJoseph Chen 		u32 size;
35dbf8423eSJoseph Chen 		u32 flags;
36dbf8423eSJoseph Chen 	} drm_mem;
37dbf8423eSJoseph Chen 	s64 reserve[8];
38dbf8423eSJoseph Chen };
39dbf8423eSJoseph Chen 
40dbf8423eSJoseph Chen static uint16_t trust_checksum(const uint8_t *buf, uint16_t len)
41dbf8423eSJoseph Chen {
42dbf8423eSJoseph Chen 	uint16_t i, checksum = 0;
43dbf8423eSJoseph Chen 
44dbf8423eSJoseph Chen 	for (i = 0; i < len; i++) {
45dbf8423eSJoseph Chen 		if (i % 2)
46dbf8423eSJoseph Chen 			checksum += buf[i] << 8;
47dbf8423eSJoseph Chen 		else
48dbf8423eSJoseph Chen 			checksum += buf[i];
49dbf8423eSJoseph Chen 	}
50dbf8423eSJoseph Chen 	checksum = ~checksum;
51dbf8423eSJoseph Chen 
52dbf8423eSJoseph Chen 	return checksum;
53dbf8423eSJoseph Chen }
54dbf8423eSJoseph Chen 
556e15146eSJoseph Chen struct memblock param_parse_atf_mem(void)
56dbf8423eSJoseph Chen {
576e15146eSJoseph Chen 	struct memblock mem;
58dbf8423eSJoseph Chen 
596e15146eSJoseph Chen 	mem.base = 0;
606e15146eSJoseph Chen 	mem.size = 0;
61dbf8423eSJoseph Chen 
62dbf8423eSJoseph Chen #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
63dbf8423eSJoseph Chen 	struct tag *t = NULL;
64dbf8423eSJoseph Chen 
65dbf8423eSJoseph Chen 	/*
66dbf8423eSJoseph Chen 	 * Get memory region of ATF
67dbf8423eSJoseph Chen 	 *
68dbf8423eSJoseph Chen 	 * 1. New way: atags info;
69dbf8423eSJoseph Chen 	 * 2. Leagcy way: 2MB size and start from ddr 0x0 offset;
70dbf8423eSJoseph Chen 	 */
71dbf8423eSJoseph Chen 	t = atags_get_tag(ATAG_ATF_MEM);
72dbf8423eSJoseph Chen 	if (t && t->u.atf_mem.size) {
736e15146eSJoseph Chen 		mem.base = t->u.atf_mem.phy_addr;
746e15146eSJoseph Chen 		mem.size = t->u.atf_mem.size;
75dbf8423eSJoseph Chen 		/* Sanity */
766e15146eSJoseph Chen 		if (mem.base + mem.size > SDRAM_OFFSET(SZ_1M)) {
77dbf8423eSJoseph Chen 			printf("%s: ATF reserved region is not within 0-1MB "
78dbf8423eSJoseph Chen 			       "offset(0x%08llx-0x%08llx)!\n",
796e15146eSJoseph Chen 			       __func__, (u64)mem.base, (u64)mem.base + mem.size);
806e15146eSJoseph Chen 			return mem;
81dbf8423eSJoseph Chen 		}
82dbf8423eSJoseph Chen 	}
83dbf8423eSJoseph Chen #endif
84dbf8423eSJoseph Chen 
85dbf8423eSJoseph Chen 	/* Legacy */
866e15146eSJoseph Chen 	if (!mem.size) {
87dbf8423eSJoseph Chen 		if (IS_ENABLED(CONFIG_ARM64) ||
88dbf8423eSJoseph Chen 		    IS_ENABLED(CONFIG_ARM64_BOOT_AARCH32)) {
896e15146eSJoseph Chen 			mem.base = SDRAM_OFFSET(0);
906e15146eSJoseph Chen 			mem.size = SZ_1M;
91dbf8423eSJoseph Chen 		}
92dbf8423eSJoseph Chen 	}
93dbf8423eSJoseph Chen 
946e15146eSJoseph Chen 	debug("ATF: 0x%llx - 0x%llx\n", (u64)mem.base, (u64)mem.base + mem.size);
95dbf8423eSJoseph Chen 
966e15146eSJoseph Chen 	return mem;
97dbf8423eSJoseph Chen }
98dbf8423eSJoseph Chen 
996e15146eSJoseph Chen struct memblock param_parse_optee_mem(void)
100dbf8423eSJoseph Chen {
101dbf8423eSJoseph Chen 	struct tos_param_t *tos_parameter;
1026e15146eSJoseph Chen 	struct memblock mem;
103dbf8423eSJoseph Chen 	u32 checksum;
104dbf8423eSJoseph Chen 
1056e15146eSJoseph Chen 	mem.base = 0;
1066e15146eSJoseph Chen 	mem.size = 0;
107dbf8423eSJoseph Chen 
108dbf8423eSJoseph Chen #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
109dbf8423eSJoseph Chen 	struct tag *t = NULL;
110dbf8423eSJoseph Chen 
111dbf8423eSJoseph Chen 	/*
112dbf8423eSJoseph Chen 	 * Get memory region of OP-TEE
113dbf8423eSJoseph Chen 	 *
114dbf8423eSJoseph Chen 	 * 1. New way: atags info;
115dbf8423eSJoseph Chen 	 * 2. Leagcy way: info in ddr 34M offset;
116dbf8423eSJoseph Chen 	 */
117dbf8423eSJoseph Chen 	t = atags_get_tag(ATAG_TOS_MEM);
118dbf8423eSJoseph Chen 	if (t && (t->u.tos_mem.tee_mem.flags == 1)) {
1196e15146eSJoseph Chen 		mem.base = t->u.tos_mem.tee_mem.phy_addr;
1206e15146eSJoseph Chen 		mem.size = t->u.tos_mem.tee_mem.size;
121dbf8423eSJoseph Chen 	}
122dbf8423eSJoseph Chen #endif
123dbf8423eSJoseph Chen 
124dbf8423eSJoseph Chen 	/* Legacy */
1256e15146eSJoseph Chen 	if (!mem.size) {
126dbf8423eSJoseph Chen 		tos_parameter =
127dbf8423eSJoseph Chen 		(struct tos_param_t *)(SDRAM_OFFSET(PARAM_OPTEE_INFO_OFFSET));
128dbf8423eSJoseph Chen 		checksum =
129dbf8423eSJoseph Chen 		trust_checksum((uint8_t *)(unsigned long)tos_parameter + 8,
130dbf8423eSJoseph Chen 			       sizeof(struct tos_param_t) - 8);
131dbf8423eSJoseph Chen 		if ((checksum == tos_parameter->checksum) &&
132dbf8423eSJoseph Chen 		    (tos_parameter->tee_mem.flags == 1)) {
1336e15146eSJoseph Chen 			mem.base = tos_parameter->tee_mem.phy_addr;
1346e15146eSJoseph Chen 			mem.size = tos_parameter->tee_mem.size;
13507ea4f34SJoseph Chen 		}
13607ea4f34SJoseph Chen 	}
13707ea4f34SJoseph Chen 
1386e15146eSJoseph Chen 	if (mem.size)
139dbf8423eSJoseph Chen 		gd->flags |= GD_FLG_BL32_ENABLED;
140dbf8423eSJoseph Chen 
1416e15146eSJoseph Chen 	debug("TOS: 0x%llx - 0x%llx\n", (u64)mem.base, (u64)mem.base + mem.size);
142dbf8423eSJoseph Chen 
1436e15146eSJoseph Chen 	return mem;
144dbf8423eSJoseph Chen }
145dbf8423eSJoseph Chen 
1466e15146eSJoseph Chen struct memblock param_parse_common_resv_mem(void)
147dbf8423eSJoseph Chen {
1486e15146eSJoseph Chen 	struct memblock mem;
149dbf8423eSJoseph Chen 
150160c99aaSJoseph Chen #if defined(CONFIG_ARM64)
151160c99aaSJoseph Chen 	mem.base = SDRAM_OFFSET(SZ_1M);
152160c99aaSJoseph Chen 	mem.size = SZ_1M;
153160c99aaSJoseph Chen /*
154160c99aaSJoseph Chen  * The ARMv8 platform enabling AArch32 mode should reserve memory the same
155160c99aaSJoseph Chen  * as AArch64 mode(because there is no difference about ATF), only some
156160c99aaSJoseph Chen  * platform has special request, they are: RK3308.
157160c99aaSJoseph Chen  */
158160c99aaSJoseph Chen #elif defined(CONFIG_ARM64_BOOT_AARCH32) && !defined(CONFIG_ROCKCHIP_RK3308)
1596e15146eSJoseph Chen 	mem.base = SDRAM_OFFSET(SZ_1M);
1606e15146eSJoseph Chen 	mem.size = SZ_1M;
1612dd104a5SJoseph Chen #else
1622dd104a5SJoseph Chen 	mem.size = 0;
1632dd104a5SJoseph Chen #endif
1646e15146eSJoseph Chen 	return mem;
165dbf8423eSJoseph Chen }
166dbf8423eSJoseph Chen 
167dbf8423eSJoseph Chen int param_parse_bootdev(char **devtype, char **devnum)
168dbf8423eSJoseph Chen {
169dbf8423eSJoseph Chen #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
170dbf8423eSJoseph Chen 	struct tag *t;
171dbf8423eSJoseph Chen 
172dbf8423eSJoseph Chen 	t = atags_get_tag(ATAG_BOOTDEV);
173dbf8423eSJoseph Chen 	if (t) {
174dbf8423eSJoseph Chen 		switch (t->u.bootdev.devtype) {
17594aee224SJason Zhu #ifdef CONFIG_DM_MMC
176dbf8423eSJoseph Chen 		case BOOT_TYPE_EMMC:
177dbf8423eSJoseph Chen 			*devtype = "mmc";
178dbf8423eSJoseph Chen 			*devnum = "0";
179dbf8423eSJoseph Chen 			break;
180dbf8423eSJoseph Chen 		case BOOT_TYPE_SD0:
181dbf8423eSJoseph Chen 		case BOOT_TYPE_SD1:
182dbf8423eSJoseph Chen 			*devtype = "mmc";
183dbf8423eSJoseph Chen 			*devnum = "1";
184c9f547d8SJason Zhu 			/*
185c9f547d8SJason Zhu 			 * If preloader does not pass sdupdate value, we treat it
186c9f547d8SJason Zhu 			 * as a unknown card and call the rkimgtest cmd to find
187c9f547d8SJason Zhu 			 * out what it is.
188c9f547d8SJason Zhu 			 *
189c9f547d8SJason Zhu 			 * If preloader pass sdupdate value as an update card,
190c9f547d8SJason Zhu 			 * we just set "sdfwupdate" to bootargs instead of
191c9f547d8SJason Zhu 			 * calling rkimgtest cmd which consumes time.
192c9f547d8SJason Zhu 			 */
193c9f547d8SJason Zhu 			if (t->u.bootdev.sdupdate == SD_UNKNOWN_CARD) {
194c9f547d8SJason Zhu 				run_command("mmc dev 1", 0);
195c9f547d8SJason Zhu 				run_command("rkimgtest mmc 1", 0);
196c9f547d8SJason Zhu 			} else if (t->u.bootdev.sdupdate == SD_UPDATE_CARD) {
197c9f547d8SJason Zhu 				env_update("bootargs", "sdfwupdate");
198c9f547d8SJason Zhu 			}
199dbf8423eSJoseph Chen 			break;
20094aee224SJason Zhu #endif
20144f308bdSJoseph Chen #if defined(CONFIG_RKNAND) || defined(CONFIG_RKNANDC_NAND)
202dbf8423eSJoseph Chen 		case BOOT_TYPE_NAND:
203dbf8423eSJoseph Chen 			*devtype = "rknand";
204dbf8423eSJoseph Chen 			*devnum = "0";
205dbf8423eSJoseph Chen 			break;
20694aee224SJason Zhu #endif
20794aee224SJason Zhu #ifdef CONFIG_RKSFC_NAND
208dbf8423eSJoseph Chen 		case BOOT_TYPE_SPI_NAND:
209dbf8423eSJoseph Chen 			*devtype = "spinand";
210dbf8423eSJoseph Chen 			*devnum = "0";
211dbf8423eSJoseph Chen 			break;
21294aee224SJason Zhu #endif
21394aee224SJason Zhu #ifdef CONFIG_RKSFC_NOR
214dbf8423eSJoseph Chen 		case BOOT_TYPE_SPI_NOR:
215dbf8423eSJoseph Chen 			*devtype = "spinor";
216dbf8423eSJoseph Chen 			*devnum = "1";
217dbf8423eSJoseph Chen 			break;
21894aee224SJason Zhu #endif
21994aee224SJason Zhu #ifdef CONFIG_DM_RAMDISK
220dbf8423eSJoseph Chen 		case BOOT_TYPE_RAM:
221dbf8423eSJoseph Chen 			*devtype = "ramdisk";
222dbf8423eSJoseph Chen 			*devnum = "0";
223dbf8423eSJoseph Chen 			break;
22494aee224SJason Zhu #endif
225c53a0c58SJason Zhu #ifdef CONFIG_NAND
226c53a0c58SJason Zhu 		case BOOT_TYPE_MTD_BLK_NAND:
227c53a0c58SJason Zhu 			*devtype = "mtd";
228c53a0c58SJason Zhu 			*devnum = "0";
229c53a0c58SJason Zhu 			break;
230c53a0c58SJason Zhu #endif
231c53a0c58SJason Zhu #ifdef CONFIG_MTD_SPI_NAND
232c53a0c58SJason Zhu 		case BOOT_TYPE_MTD_BLK_SPI_NAND:
233c53a0c58SJason Zhu 			*devtype = "mtd";
234c53a0c58SJason Zhu 			*devnum = "1";
235c53a0c58SJason Zhu 			break;
236c53a0c58SJason Zhu #endif
237c53a0c58SJason Zhu #ifdef CONFIG_SPI_FLASH_MTD
238c53a0c58SJason Zhu 		case BOOT_TYPE_MTD_BLK_SPI_NOR:
239c53a0c58SJason Zhu 			*devtype = "mtd";
240c53a0c58SJason Zhu 			*devnum = "2";
241c53a0c58SJason Zhu 			break;
242c53a0c58SJason Zhu #endif
243dbf8423eSJoseph Chen 		default:
244dbf8423eSJoseph Chen 			printf("Unknown bootdev type: 0x%x\n",
245dbf8423eSJoseph Chen 			       t->u.bootdev.devtype);
246dbf8423eSJoseph Chen 			return -EINVAL;
247dbf8423eSJoseph Chen 		}
248dbf8423eSJoseph Chen 
249dbf8423eSJoseph Chen 		return 0;
250dbf8423eSJoseph Chen 	}
251dbf8423eSJoseph Chen #endif
252dbf8423eSJoseph Chen 
253dbf8423eSJoseph Chen 	return -ENOSYS;
254dbf8423eSJoseph Chen }
2554e92aae1SJoseph Chen #endif
256b9bc76b4SJoseph Chen 
257ced10dbeSJoseph Chen static phys_size_t ddr_mem_get_usable_size(u64 base, u64 size)
258ced10dbeSJoseph Chen {
2593ceae109SJoseph Chen 	return (base + size >= CONFIG_SYS_SDRAM_BASE + SDRAM_MAX_SIZE) ?
2603ceae109SJoseph Chen 	       (CONFIG_SYS_SDRAM_BASE + SDRAM_MAX_SIZE - base) : size;
261ced10dbeSJoseph Chen }
262ced10dbeSJoseph Chen 
263b9bc76b4SJoseph Chen struct memblock *param_parse_ddr_mem(int *out_count)
264b9bc76b4SJoseph Chen {
265b9bc76b4SJoseph Chen 	struct udevice *dev;
266b9bc76b4SJoseph Chen 	struct memblock *mem;
267b9bc76b4SJoseph Chen 	struct ram_info ram;
268b9bc76b4SJoseph Chen 	int i, ret, count;
269b9bc76b4SJoseph Chen 
270b9bc76b4SJoseph Chen 	/*
271b9bc76b4SJoseph Chen 	 * Get memory region of DDR
272b9bc76b4SJoseph Chen 	 *
273b9bc76b4SJoseph Chen 	 * 1. New: atags info;
274b9bc76b4SJoseph Chen 	 * 2. Leagcy: os register;
275b9bc76b4SJoseph Chen 	 */
276b9bc76b4SJoseph Chen #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
277b9bc76b4SJoseph Chen 	struct tag *t;
2780453d738SJoseph Chen 	u64 base, size;
2790453d738SJoseph Chen 	int n;
280b9bc76b4SJoseph Chen 
281b9bc76b4SJoseph Chen 	t = atags_get_tag(ATAG_DDR_MEM);
282b9bc76b4SJoseph Chen 	if (t && t->u.ddr_mem.count) {
283*d8e6f8d0SJoseph Chen 		/* extend top ram size */
284*d8e6f8d0SJoseph Chen 		if (t->u.ddr_mem.flags & DDR_MEM_FLG_EXT_TOP)
285*d8e6f8d0SJoseph Chen 			gd->ram_top_ext_size = t->u.ddr_mem.data[0];
286*d8e6f8d0SJoseph Chen 
287*d8e6f8d0SJoseph Chen 		/* normal ram size */
288b9bc76b4SJoseph Chen 		count = t->u.ddr_mem.count;
2890453d738SJoseph Chen 		mem = calloc(count + MEM_RESV_COUNT, sizeof(*mem));
290b9bc76b4SJoseph Chen 		if (!mem) {
291b9bc76b4SJoseph Chen 			printf("Calloc ddr memory failed\n");
292b9bc76b4SJoseph Chen 			return 0;
293b9bc76b4SJoseph Chen 		}
294b9bc76b4SJoseph Chen 
2950453d738SJoseph Chen 		for (i = 0, n = 0; i < count; i++, n++) {
2960453d738SJoseph Chen 			base = t->u.ddr_mem.bank[i];
2970453d738SJoseph Chen 			size = t->u.ddr_mem.bank[i + count];
2980453d738SJoseph Chen 
2990453d738SJoseph Chen 			/* 0~4GB */
3000453d738SJoseph Chen 			if (base < SZ_4GB) {
3010453d738SJoseph Chen 				mem[n].base = base;
3020453d738SJoseph Chen 				mem[n].size = ddr_mem_get_usable_size(base, size);
3030453d738SJoseph Chen 				if (base + size > SZ_4GB) {
3040453d738SJoseph Chen 					n++;
3050453d738SJoseph Chen 					mem[n].base_u64 = SZ_4GB;
3060453d738SJoseph Chen 					mem[n].size_u64 = base + size - SZ_4GB;
3070453d738SJoseph Chen 				}
3080453d738SJoseph Chen 			} else {
3090453d738SJoseph Chen 				/* 4GB+ */
3100453d738SJoseph Chen 				mem[n].base_u64 = base;
3110453d738SJoseph Chen 				mem[n].size_u64 = size;
312b9bc76b4SJoseph Chen 			}
313b9bc76b4SJoseph Chen 
3140453d738SJoseph Chen 			assert(n < count + MEM_RESV_COUNT);
3150453d738SJoseph Chen 		}
3160453d738SJoseph Chen 
3170453d738SJoseph Chen 		*out_count = n;
318b9bc76b4SJoseph Chen 		return mem;
319b9bc76b4SJoseph Chen 	}
320b9bc76b4SJoseph Chen #endif
321b9bc76b4SJoseph Chen 
322b9bc76b4SJoseph Chen 	/* Leagcy */
323b9bc76b4SJoseph Chen 	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
324b9bc76b4SJoseph Chen 	if (ret) {
325b9bc76b4SJoseph Chen 		debug("DRAM init failed: %d\n", ret);
326b9bc76b4SJoseph Chen 		return NULL;
327b9bc76b4SJoseph Chen 	}
328b9bc76b4SJoseph Chen 	ret = ram_get_info(dev, &ram);
329b9bc76b4SJoseph Chen 	if (ret) {
330b9bc76b4SJoseph Chen 		debug("Cannot get DRAM size: %d\n", ret);
331b9bc76b4SJoseph Chen 		return NULL;
332b9bc76b4SJoseph Chen 	}
333b9bc76b4SJoseph Chen 
334b9bc76b4SJoseph Chen 	debug("SDRAM base=%lx, size=%lx\n",
335b9bc76b4SJoseph Chen 	      (unsigned long)ram.base, (unsigned long)ram.size);
336b9bc76b4SJoseph Chen 
337b9bc76b4SJoseph Chen 	count = 1;
338b9bc76b4SJoseph Chen 	mem = calloc(1, sizeof(*mem));
339b9bc76b4SJoseph Chen 	if (!mem) {
340b9bc76b4SJoseph Chen 		printf("Calloc ddr memory failed\n");
341b9bc76b4SJoseph Chen 		return 0;
342b9bc76b4SJoseph Chen 	}
343b9bc76b4SJoseph Chen 
344b9bc76b4SJoseph Chen 	for (i = 0; i < count; i++) {
345b9bc76b4SJoseph Chen 		mem[i].base = CONFIG_SYS_SDRAM_BASE;
346ced10dbeSJoseph Chen 		mem[i].size = ddr_mem_get_usable_size(mem[i].base, ram.size);
347b9bc76b4SJoseph Chen 	}
348b9bc76b4SJoseph Chen 
349b9bc76b4SJoseph Chen 	*out_count = count;
350b9bc76b4SJoseph Chen 	return mem;
351b9bc76b4SJoseph Chen }
352045d3eaaSJoseph Chen 
3531a4d12c4SJoseph Chen #ifndef CONFIG_BIDRAM
3541a4d12c4SJoseph Chen /*
3551a4d12c4SJoseph Chen  * init_bank=0: called from dram_init_banksize()
3561a4d12c4SJoseph Chen  * init_bank=0: called from dram_init()
3571a4d12c4SJoseph Chen  */
3581a4d12c4SJoseph Chen phys_size_t param_simple_parse_ddr_mem(int init_bank)
3591a4d12c4SJoseph Chen {
3601a4d12c4SJoseph Chen 	struct memblock *list;
3611a4d12c4SJoseph Chen 	int i, count;
3621a4d12c4SJoseph Chen 
3631a4d12c4SJoseph Chen 	list = param_parse_ddr_mem(&count);
3641a4d12c4SJoseph Chen 	if (!list) {
3651a4d12c4SJoseph Chen 		printf("Can't get dram banks\n");
3661a4d12c4SJoseph Chen 		return 0;
3671a4d12c4SJoseph Chen 	}
3681a4d12c4SJoseph Chen 
3691a4d12c4SJoseph Chen 	if (count > CONFIG_NR_DRAM_BANKS) {
3701a4d12c4SJoseph Chen 		printf("Dram banks num=%d, over %d\n", count, CONFIG_NR_DRAM_BANKS);
3711a4d12c4SJoseph Chen 		return 0;
3721a4d12c4SJoseph Chen 	}
3731a4d12c4SJoseph Chen 
3741a4d12c4SJoseph Chen 	if (!init_bank) {
3751a4d12c4SJoseph Chen 		i = count - 1;
3761a4d12c4SJoseph Chen 		return ddr_mem_get_usable_size(list[i].base, list[i].size);
3771a4d12c4SJoseph Chen 	}
3781a4d12c4SJoseph Chen 
3791a4d12c4SJoseph Chen 	for (i = 0; i < count; i++) {
3801a4d12c4SJoseph Chen 		gd->bd->bi_dram[i].start = list[i].base;
3811a4d12c4SJoseph Chen 		gd->bd->bi_dram[i].size =
3821a4d12c4SJoseph Chen 			ddr_mem_get_usable_size(list[i].base, list[i].size);
3831a4d12c4SJoseph Chen 		debug("bank[%d]: 0x%08lx - 0x%08lx\n", i,
3841a4d12c4SJoseph Chen 		      (ulong)gd->bd->bi_dram[i].start,
3851a4d12c4SJoseph Chen 		      (ulong)gd->bd->bi_dram[i].start +
3861a4d12c4SJoseph Chen 		      (ulong)gd->bd->bi_dram[i].size);
3871a4d12c4SJoseph Chen 	}
3881a4d12c4SJoseph Chen 
3891a4d12c4SJoseph Chen 	return 0;
3901a4d12c4SJoseph Chen }
3911a4d12c4SJoseph Chen #endif
3921a4d12c4SJoseph Chen 
393045d3eaaSJoseph Chen int param_parse_pre_serial(void)
394045d3eaaSJoseph Chen {
395045d3eaaSJoseph Chen #if defined(CONFIG_ROCKCHIP_PRELOADER_SERIAL) && \
396045d3eaaSJoseph Chen     defined(CONFIG_ROCKCHIP_PRELOADER_ATAGS)
397045d3eaaSJoseph Chen 	struct tag *t;
398045d3eaaSJoseph Chen 
399045d3eaaSJoseph Chen 	t = atags_get_tag(ATAG_SERIAL);
400045d3eaaSJoseph Chen 	if (t) {
401045d3eaaSJoseph Chen 		gd->serial.using_pre_serial = 1;
402045d3eaaSJoseph Chen 		gd->serial.enable = t->u.serial.enable;
403045d3eaaSJoseph Chen 		gd->serial.baudrate = t->u.serial.baudrate;
404045d3eaaSJoseph Chen 		gd->serial.addr = t->u.serial.addr;
405045d3eaaSJoseph Chen 		gd->serial.id = t->u.serial.id;
406045d3eaaSJoseph Chen 		gd->baudrate = CONFIG_BAUDRATE;
407045d3eaaSJoseph Chen 		debug("preloader: enable=%d, addr=0x%lx, baudrate=%d, id=%d\n",
408045d3eaaSJoseph Chen 		      gd->serial.enable, gd->serial.addr,
409045d3eaaSJoseph Chen 		      gd->serial.baudrate, gd->serial.id);
410045d3eaaSJoseph Chen 	} else
411045d3eaaSJoseph Chen #endif
412045d3eaaSJoseph Chen 	{
413045d3eaaSJoseph Chen 		gd->baudrate = CONFIG_BAUDRATE;
414045d3eaaSJoseph Chen 		gd->serial.baudrate = CONFIG_BAUDRATE;
415045d3eaaSJoseph Chen 		gd->serial.addr = CONFIG_DEBUG_UART_BASE;
416045d3eaaSJoseph Chen 	}
417045d3eaaSJoseph Chen 
418045d3eaaSJoseph Chen 	return 0;
419045d3eaaSJoseph Chen }
420045d3eaaSJoseph Chen 
421045d3eaaSJoseph Chen int param_parse_pubkey_fuse_programmed(void)
422045d3eaaSJoseph Chen {
423045d3eaaSJoseph Chen #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
424045d3eaaSJoseph Chen 	struct tag *t;
425045d3eaaSJoseph Chen 
426045d3eaaSJoseph Chen 	t = atags_get_tag(ATAG_PUB_KEY);
427045d3eaaSJoseph Chen 	if (t) {
428045d3eaaSJoseph Chen 		/* Pass if efuse/otp programmed */
429045d3eaaSJoseph Chen 		if (t->u.pub_key.flag == PUBKEY_FUSE_PROGRAMMED)
430045d3eaaSJoseph Chen 			env_update("bootargs", "fuse.programmed=1");
431045d3eaaSJoseph Chen 		else
432045d3eaaSJoseph Chen 			env_update("bootargs", "fuse.programmed=0");
433045d3eaaSJoseph Chen 	}
434045d3eaaSJoseph Chen #endif
435045d3eaaSJoseph Chen 	return 0;
436045d3eaaSJoseph Chen }
437045d3eaaSJoseph Chen 
438