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
trust_checksum(const uint8_t * buf,uint16_t len)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
param_parse_atf_mem(void)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
param_parse_optee_mem(void)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
param_parse_common_resv_mem(void)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
param_parse_assign_bootdev(char ** devtype,char ** devnum)1675029b474SJoseph Chen int param_parse_assign_bootdev(char **devtype, char **devnum)
1685029b474SJoseph Chen {
1695029b474SJoseph Chen char *bootdev_str = CONFIG_ROCKCHIP_BOOTDEV;
1705029b474SJoseph Chen char *type, *num;
1715029b474SJoseph Chen
1725029b474SJoseph Chen num = strchr(bootdev_str, ' ');
1735029b474SJoseph Chen if (!num)
1745029b474SJoseph Chen return -ENODEV;
1755029b474SJoseph Chen
1765029b474SJoseph Chen type = strdup(bootdev_str);
1775029b474SJoseph Chen type[num - bootdev_str] = 0;
1785029b474SJoseph Chen num++;
1795029b474SJoseph Chen
1805029b474SJoseph Chen *devtype = type;
1815029b474SJoseph Chen *devnum = num;
1825029b474SJoseph Chen
1835029b474SJoseph Chen return 0;
1845029b474SJoseph Chen }
1855029b474SJoseph Chen
param_parse_atags_bootdev(char ** devtype,char ** devnum)1865029b474SJoseph Chen int param_parse_atags_bootdev(char **devtype, char **devnum)
187dbf8423eSJoseph Chen {
188dbf8423eSJoseph Chen #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
189dbf8423eSJoseph Chen struct tag *t;
190dbf8423eSJoseph Chen
191dbf8423eSJoseph Chen t = atags_get_tag(ATAG_BOOTDEV);
192dbf8423eSJoseph Chen if (t) {
193dbf8423eSJoseph Chen switch (t->u.bootdev.devtype) {
19494aee224SJason Zhu #ifdef CONFIG_DM_MMC
195dbf8423eSJoseph Chen case BOOT_TYPE_EMMC:
196dbf8423eSJoseph Chen *devtype = "mmc";
197dbf8423eSJoseph Chen *devnum = "0";
198dbf8423eSJoseph Chen break;
199dbf8423eSJoseph Chen case BOOT_TYPE_SD0:
200dbf8423eSJoseph Chen case BOOT_TYPE_SD1:
201dbf8423eSJoseph Chen *devtype = "mmc";
202dbf8423eSJoseph Chen *devnum = "1";
203c9f547d8SJason Zhu /*
204c9f547d8SJason Zhu * If preloader does not pass sdupdate value, we treat it
205c9f547d8SJason Zhu * as a unknown card and call the rkimgtest cmd to find
206c9f547d8SJason Zhu * out what it is.
207c9f547d8SJason Zhu *
208c9f547d8SJason Zhu * If preloader pass sdupdate value as an update card,
209c9f547d8SJason Zhu * we just set "sdfwupdate" to bootargs instead of
210c9f547d8SJason Zhu * calling rkimgtest cmd which consumes time.
211c9f547d8SJason Zhu */
212c9f547d8SJason Zhu if (t->u.bootdev.sdupdate == SD_UNKNOWN_CARD) {
213c9f547d8SJason Zhu run_command("mmc dev 1", 0);
214c9f547d8SJason Zhu run_command("rkimgtest mmc 1", 0);
215c9f547d8SJason Zhu } else if (t->u.bootdev.sdupdate == SD_UPDATE_CARD) {
216c9f547d8SJason Zhu env_update("bootargs", "sdfwupdate");
217c9f547d8SJason Zhu }
218dbf8423eSJoseph Chen break;
21994aee224SJason Zhu #endif
22044f308bdSJoseph Chen #if defined(CONFIG_RKNAND) || defined(CONFIG_RKNANDC_NAND)
221dbf8423eSJoseph Chen case BOOT_TYPE_NAND:
222dbf8423eSJoseph Chen *devtype = "rknand";
223dbf8423eSJoseph Chen *devnum = "0";
224dbf8423eSJoseph Chen break;
22594aee224SJason Zhu #endif
22694aee224SJason Zhu #ifdef CONFIG_RKSFC_NAND
227dbf8423eSJoseph Chen case BOOT_TYPE_SPI_NAND:
228dbf8423eSJoseph Chen *devtype = "spinand";
229dbf8423eSJoseph Chen *devnum = "0";
230dbf8423eSJoseph Chen break;
23194aee224SJason Zhu #endif
23294aee224SJason Zhu #ifdef CONFIG_RKSFC_NOR
233dbf8423eSJoseph Chen case BOOT_TYPE_SPI_NOR:
234dbf8423eSJoseph Chen *devtype = "spinor";
235dbf8423eSJoseph Chen *devnum = "1";
236dbf8423eSJoseph Chen break;
23794aee224SJason Zhu #endif
23894aee224SJason Zhu #ifdef CONFIG_DM_RAMDISK
239dbf8423eSJoseph Chen case BOOT_TYPE_RAM:
240dbf8423eSJoseph Chen *devtype = "ramdisk";
241dbf8423eSJoseph Chen *devnum = "0";
242dbf8423eSJoseph Chen break;
24394aee224SJason Zhu #endif
244c53a0c58SJason Zhu #ifdef CONFIG_NAND
245c53a0c58SJason Zhu case BOOT_TYPE_MTD_BLK_NAND:
246c53a0c58SJason Zhu *devtype = "mtd";
247c53a0c58SJason Zhu *devnum = "0";
248c53a0c58SJason Zhu break;
249c53a0c58SJason Zhu #endif
250c53a0c58SJason Zhu #ifdef CONFIG_MTD_SPI_NAND
251c53a0c58SJason Zhu case BOOT_TYPE_MTD_BLK_SPI_NAND:
252c53a0c58SJason Zhu *devtype = "mtd";
253c53a0c58SJason Zhu *devnum = "1";
254c53a0c58SJason Zhu break;
255c53a0c58SJason Zhu #endif
256c53a0c58SJason Zhu #ifdef CONFIG_SPI_FLASH_MTD
257c53a0c58SJason Zhu case BOOT_TYPE_MTD_BLK_SPI_NOR:
258c53a0c58SJason Zhu *devtype = "mtd";
259c53a0c58SJason Zhu *devnum = "2";
260c53a0c58SJason Zhu break;
261c53a0c58SJason Zhu #endif
262bc113e2aSYifeng Zhao #ifdef CONFIG_UFS
263bc113e2aSYifeng Zhao case BOOT_TYPE_UFS:
264bc113e2aSYifeng Zhao *devtype = "scsi";
265bc113e2aSYifeng Zhao *devnum = "0";
266bc113e2aSYifeng Zhao break;
267bc113e2aSYifeng Zhao #endif
268dbf8423eSJoseph Chen default:
269dbf8423eSJoseph Chen printf("Unknown bootdev type: 0x%x\n",
270dbf8423eSJoseph Chen t->u.bootdev.devtype);
271dbf8423eSJoseph Chen return -EINVAL;
272dbf8423eSJoseph Chen }
273dbf8423eSJoseph Chen
274dbf8423eSJoseph Chen return 0;
275dbf8423eSJoseph Chen }
276dbf8423eSJoseph Chen #endif
277dbf8423eSJoseph Chen
278dbf8423eSJoseph Chen return -ENOSYS;
279dbf8423eSJoseph Chen }
2804e92aae1SJoseph Chen #endif
281b9bc76b4SJoseph Chen
ddr_mem_get_usable_size(u64 base,u64 size)282*1a7a2cb2SXuhui Lin phys_size_t ddr_mem_get_usable_size(u64 base, u64 size)
283ced10dbeSJoseph Chen {
2843ceae109SJoseph Chen return (base + size >= CONFIG_SYS_SDRAM_BASE + SDRAM_MAX_SIZE) ?
2853ceae109SJoseph Chen (CONFIG_SYS_SDRAM_BASE + SDRAM_MAX_SIZE - base) : size;
286ced10dbeSJoseph Chen }
287ced10dbeSJoseph Chen
param_parse_ddr_mem(int * out_count)288b9bc76b4SJoseph Chen struct memblock *param_parse_ddr_mem(int *out_count)
289b9bc76b4SJoseph Chen {
290b9bc76b4SJoseph Chen struct udevice *dev;
291b9bc76b4SJoseph Chen struct memblock *mem;
292b9bc76b4SJoseph Chen struct ram_info ram;
293b9bc76b4SJoseph Chen int i, ret, count;
294b9bc76b4SJoseph Chen
295b9bc76b4SJoseph Chen /*
296b9bc76b4SJoseph Chen * Get memory region of DDR
297b9bc76b4SJoseph Chen *
298b9bc76b4SJoseph Chen * 1. New: atags info;
299b9bc76b4SJoseph Chen * 2. Leagcy: os register;
300b9bc76b4SJoseph Chen */
301b9bc76b4SJoseph Chen #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
302b9bc76b4SJoseph Chen struct tag *t;
3030453d738SJoseph Chen u64 base, size;
3040453d738SJoseph Chen int n;
305b9bc76b4SJoseph Chen
306b9bc76b4SJoseph Chen t = atags_get_tag(ATAG_DDR_MEM);
307b9bc76b4SJoseph Chen if (t && t->u.ddr_mem.count) {
308d8e6f8d0SJoseph Chen /* extend top ram size */
309d8e6f8d0SJoseph Chen if (t->u.ddr_mem.flags & DDR_MEM_FLG_EXT_TOP)
310d8e6f8d0SJoseph Chen gd->ram_top_ext_size = t->u.ddr_mem.data[0];
311d8e6f8d0SJoseph Chen
312d8e6f8d0SJoseph Chen /* normal ram size */
313b9bc76b4SJoseph Chen count = t->u.ddr_mem.count;
3140453d738SJoseph Chen mem = calloc(count + MEM_RESV_COUNT, sizeof(*mem));
315b9bc76b4SJoseph Chen if (!mem) {
316b9bc76b4SJoseph Chen printf("Calloc ddr memory failed\n");
317b9bc76b4SJoseph Chen return 0;
318b9bc76b4SJoseph Chen }
319b9bc76b4SJoseph Chen
3200453d738SJoseph Chen for (i = 0, n = 0; i < count; i++, n++) {
3210453d738SJoseph Chen base = t->u.ddr_mem.bank[i];
3220453d738SJoseph Chen size = t->u.ddr_mem.bank[i + count];
3230453d738SJoseph Chen
3240453d738SJoseph Chen /* 0~4GB */
3250453d738SJoseph Chen if (base < SZ_4GB) {
3260453d738SJoseph Chen mem[n].base = base;
3270453d738SJoseph Chen mem[n].size = ddr_mem_get_usable_size(base, size);
3280453d738SJoseph Chen if (base + size > SZ_4GB) {
3290453d738SJoseph Chen n++;
3300453d738SJoseph Chen mem[n].base_u64 = SZ_4GB;
3310453d738SJoseph Chen mem[n].size_u64 = base + size - SZ_4GB;
3320453d738SJoseph Chen }
3330453d738SJoseph Chen } else {
3340453d738SJoseph Chen /* 4GB+ */
3350453d738SJoseph Chen mem[n].base_u64 = base;
3360453d738SJoseph Chen mem[n].size_u64 = size;
337b9bc76b4SJoseph Chen }
338b9bc76b4SJoseph Chen
3390453d738SJoseph Chen assert(n < count + MEM_RESV_COUNT);
3400453d738SJoseph Chen }
3410453d738SJoseph Chen
3420453d738SJoseph Chen *out_count = n;
343b9bc76b4SJoseph Chen return mem;
344b9bc76b4SJoseph Chen }
345b9bc76b4SJoseph Chen #endif
346b9bc76b4SJoseph Chen
347b9bc76b4SJoseph Chen /* Leagcy */
348b9bc76b4SJoseph Chen ret = uclass_get_device(UCLASS_RAM, 0, &dev);
349b9bc76b4SJoseph Chen if (ret) {
350b9bc76b4SJoseph Chen debug("DRAM init failed: %d\n", ret);
351b9bc76b4SJoseph Chen return NULL;
352b9bc76b4SJoseph Chen }
353b9bc76b4SJoseph Chen ret = ram_get_info(dev, &ram);
354b9bc76b4SJoseph Chen if (ret) {
355b9bc76b4SJoseph Chen debug("Cannot get DRAM size: %d\n", ret);
356b9bc76b4SJoseph Chen return NULL;
357b9bc76b4SJoseph Chen }
358b9bc76b4SJoseph Chen
359b9bc76b4SJoseph Chen debug("SDRAM base=%lx, size=%lx\n",
360b9bc76b4SJoseph Chen (unsigned long)ram.base, (unsigned long)ram.size);
361b9bc76b4SJoseph Chen
362b9bc76b4SJoseph Chen count = 1;
363b9bc76b4SJoseph Chen mem = calloc(1, sizeof(*mem));
364b9bc76b4SJoseph Chen if (!mem) {
365b9bc76b4SJoseph Chen printf("Calloc ddr memory failed\n");
366b9bc76b4SJoseph Chen return 0;
367b9bc76b4SJoseph Chen }
368b9bc76b4SJoseph Chen
369b9bc76b4SJoseph Chen for (i = 0; i < count; i++) {
370b9bc76b4SJoseph Chen mem[i].base = CONFIG_SYS_SDRAM_BASE;
371ced10dbeSJoseph Chen mem[i].size = ddr_mem_get_usable_size(mem[i].base, ram.size);
372b9bc76b4SJoseph Chen }
373b9bc76b4SJoseph Chen
374b9bc76b4SJoseph Chen *out_count = count;
375b9bc76b4SJoseph Chen return mem;
376b9bc76b4SJoseph Chen }
377045d3eaaSJoseph Chen
3781a4d12c4SJoseph Chen #ifndef CONFIG_BIDRAM
3791a4d12c4SJoseph Chen /*
3801a4d12c4SJoseph Chen * init_bank=0: called from dram_init_banksize()
3811a4d12c4SJoseph Chen * init_bank=0: called from dram_init()
3821a4d12c4SJoseph Chen */
param_simple_parse_ddr_mem(int init_bank)3831a4d12c4SJoseph Chen phys_size_t param_simple_parse_ddr_mem(int init_bank)
3841a4d12c4SJoseph Chen {
3851a4d12c4SJoseph Chen struct memblock *list;
3861a4d12c4SJoseph Chen int i, count;
3871a4d12c4SJoseph Chen
3881a4d12c4SJoseph Chen list = param_parse_ddr_mem(&count);
3891a4d12c4SJoseph Chen if (!list) {
3901a4d12c4SJoseph Chen printf("Can't get dram banks\n");
3911a4d12c4SJoseph Chen return 0;
3921a4d12c4SJoseph Chen }
3931a4d12c4SJoseph Chen
3941a4d12c4SJoseph Chen if (count > CONFIG_NR_DRAM_BANKS) {
3951a4d12c4SJoseph Chen printf("Dram banks num=%d, over %d\n", count, CONFIG_NR_DRAM_BANKS);
3961a4d12c4SJoseph Chen return 0;
3971a4d12c4SJoseph Chen }
3981a4d12c4SJoseph Chen
3991a4d12c4SJoseph Chen if (!init_bank) {
4001a4d12c4SJoseph Chen i = count - 1;
4011a4d12c4SJoseph Chen return ddr_mem_get_usable_size(list[i].base, list[i].size);
4021a4d12c4SJoseph Chen }
4031a4d12c4SJoseph Chen
4041a4d12c4SJoseph Chen for (i = 0; i < count; i++) {
4051a4d12c4SJoseph Chen gd->bd->bi_dram[i].start = list[i].base;
4061a4d12c4SJoseph Chen gd->bd->bi_dram[i].size =
4071a4d12c4SJoseph Chen ddr_mem_get_usable_size(list[i].base, list[i].size);
4081a4d12c4SJoseph Chen debug("bank[%d]: 0x%08lx - 0x%08lx\n", i,
4091a4d12c4SJoseph Chen (ulong)gd->bd->bi_dram[i].start,
4101a4d12c4SJoseph Chen (ulong)gd->bd->bi_dram[i].start +
4111a4d12c4SJoseph Chen (ulong)gd->bd->bi_dram[i].size);
4121a4d12c4SJoseph Chen }
4131a4d12c4SJoseph Chen
4141a4d12c4SJoseph Chen return 0;
4151a4d12c4SJoseph Chen }
4161a4d12c4SJoseph Chen #endif
4171a4d12c4SJoseph Chen
param_parse_pre_serial(int * flags)4189d10124aSJoseph Chen int param_parse_pre_serial(int *flags)
419045d3eaaSJoseph Chen {
420045d3eaaSJoseph Chen #if defined(CONFIG_ROCKCHIP_PRELOADER_SERIAL) && \
421045d3eaaSJoseph Chen defined(CONFIG_ROCKCHIP_PRELOADER_ATAGS)
422045d3eaaSJoseph Chen struct tag *t;
423045d3eaaSJoseph Chen
424045d3eaaSJoseph Chen t = atags_get_tag(ATAG_SERIAL);
425045d3eaaSJoseph Chen if (t) {
426045d3eaaSJoseph Chen gd->serial.using_pre_serial = 1;
427045d3eaaSJoseph Chen gd->serial.enable = t->u.serial.enable;
428045d3eaaSJoseph Chen gd->serial.baudrate = t->u.serial.baudrate;
429045d3eaaSJoseph Chen gd->serial.addr = t->u.serial.addr;
430045d3eaaSJoseph Chen gd->serial.id = t->u.serial.id;
431045d3eaaSJoseph Chen gd->baudrate = CONFIG_BAUDRATE;
4329d10124aSJoseph Chen if (!gd->serial.enable && flags)
4339d10124aSJoseph Chen *flags |= GD_FLG_DISABLE_CONSOLE;
434045d3eaaSJoseph Chen debug("preloader: enable=%d, addr=0x%lx, baudrate=%d, id=%d\n",
435045d3eaaSJoseph Chen gd->serial.enable, gd->serial.addr,
436045d3eaaSJoseph Chen gd->serial.baudrate, gd->serial.id);
437045d3eaaSJoseph Chen } else
438045d3eaaSJoseph Chen #endif
439045d3eaaSJoseph Chen {
440045d3eaaSJoseph Chen gd->baudrate = CONFIG_BAUDRATE;
441045d3eaaSJoseph Chen gd->serial.baudrate = CONFIG_BAUDRATE;
442045d3eaaSJoseph Chen gd->serial.addr = CONFIG_DEBUG_UART_BASE;
443045d3eaaSJoseph Chen }
444045d3eaaSJoseph Chen
445045d3eaaSJoseph Chen return 0;
446045d3eaaSJoseph Chen }
447045d3eaaSJoseph Chen
param_parse_pubkey_fuse_programmed(void)448045d3eaaSJoseph Chen int param_parse_pubkey_fuse_programmed(void)
449045d3eaaSJoseph Chen {
450045d3eaaSJoseph Chen #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
451045d3eaaSJoseph Chen struct tag *t;
452045d3eaaSJoseph Chen
453045d3eaaSJoseph Chen t = atags_get_tag(ATAG_PUB_KEY);
454045d3eaaSJoseph Chen if (t) {
455045d3eaaSJoseph Chen /* Pass if efuse/otp programmed */
456045d3eaaSJoseph Chen if (t->u.pub_key.flag == PUBKEY_FUSE_PROGRAMMED)
457045d3eaaSJoseph Chen env_update("bootargs", "fuse.programmed=1");
458045d3eaaSJoseph Chen else
459045d3eaaSJoseph Chen env_update("bootargs", "fuse.programmed=0");
460045d3eaaSJoseph Chen }
461045d3eaaSJoseph Chen #endif
462045d3eaaSJoseph Chen return 0;
463045d3eaaSJoseph Chen }
464045d3eaaSJoseph Chen
465